Concept
Printing values
function checkValues() {
const sheet = SpreadsheetApp.getActiveSheet();
const value = sheet.getRange('B2').getValue();
console.log('B2 contains:', value);
console.log('Type is:', typeof value);
}
Run it and look at the Execution log panel at the bottom of the editor.
console.log— the modern choice. Also writes to the Executions page, so you can see logs from triggered runs later. Useconsole.warn/console.errorfor problems.Logger.log— older; shows in the execution log of the current run only.
Tip: printing typeof value solves many bugs. A cell you think holds a number may actually hold the text '1,200'.
Using the debugger
- Click the line number on the left to set a breakpoint (a purple dot appears).
- Pick your function and click Debug (not Run).
- The script pauses at the breakpoint. The right panel shows every variable's current value.
- Use Step over to run one line at a time, Resume to continue.
Use the debugger when a loop gives a wrong result and you want to watch the values change row by row.
Reading error messages
A typical error:
TypeError: Cannot read properties of null (reading 'getRange')
at readStock (Code:3:24)
- What happened: you called
.getRangeon something that isnull. - Where: file
Code, line 3. - Usual cause:
getSheetByName('Stock')returnednullbecause the tab is named differently (e.g.'stock'or'Stock 'with a space).
Common errors and their usual causes:
| Error | Usual cause |
|---|---|
Cannot read properties of null |
Sheet/range name doesn't exist |
The number of rows in the data does not match the number of rows in the range |
setValues array size ≠ range size |
Exception: You do not have permission to call ... |
Using Gmail/Drive from a simple trigger or custom function |
Exceeded maximum execution time |
Script ran past ~6 minutes |
ReferenceError: x is not defined |
Typo in a variable or function name |
The Executions page
Click the Executions icon (list) on the left. Every run appears here — manual, triggered, or from a web app — with its status (Completed / Failed), duration, and logs. When a scheduled trigger fails at 3 a.m., this is where you find out why.
Handling errors with try...catch
function safeRead() {
try {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Stock');
if (!sheet) {
throw new Error('Tab "Stock" not found');
}
const qty = sheet.getRange('B2').getValue();
console.log('Qty:', qty);
} catch (err) {
console.error('Something went wrong: ' + err.message);
// Optionally email yourself:
// MailApp.sendEmail('you@example.com', 'Script error', err.stack);
}
}
Use try...catch in triggered scripts so a failure is logged clearly (or emailed to you) instead of failing silently.
Key points
console.log+ the Executions page = your main debugging tools.- Read the error's line number first, then check names and data types.
- Wrap scheduled jobs in
try...catchand report errors.