GAS『Invalid Argument: Expected』の原因と対処法
- 作成日 2025.10.21
- その他
Apps Scriptが受け取った引数の型・形式・個数がメソッドの期待と違うと発生する。A1表記と数値の取り違え、2次元配列のサイズ不一致、Date型やURL文字列の誤り、sendEmailのオーバーロード間違い、fetchのオプション型不整合などが典型。よくある発生条件を整理し、すぐに直せる修正パターンをまとめた。
- 1. エラーの意味と代表メッセージ
- 2. 発生条件の早見表
- 3. ケース1:getRangeの指定ミス(A1表記 vs 行列指定)
- 4. ケース2:setValuesは“2次元配列+サイズ一致”が必須
- 5. ケース3:Dateを期待する場所に文字列を渡している
- 6. ケース4:UrlFetchApp.fetch / fetchAll のオプション型不整合
- 7. ケース5:MailApp.sendEmailのオーバーロード取り違え
- 8. ケース6:JSON.parse/JSON.stringifyの引数型が不正
- 9. ケース7:CacheService.putの秒数範囲、キー/値の型
- 10. ケース8:Trigger作成APIの引数(関数名・対象・間隔)
- 11. ケース9:Advanced Sheets/Drive APIのボディ構造が仕様外
- 12. ケース10:配列/オブジェクトAPIでのコールバック型ミス
- 13. 入力検証のテンプレ(事前に“期待どおりか”を保証)
- 14. 診断のコツ(どの引数が不正かを素早く突き止める)
- 15. チェックリスト(上から順に潰す)
エラーの意味と代表メッセージ
「Invalid argument: Expected …」や「Invalid argument: url」「Invalid argument: id」など、呼び出し先が“この位置には〇〇型/形式の引数が必要”と判断したときに出る。多くは型の取り違えか、値のラップ/展開方法のミス。
発生条件の早見表
・getRangeにA1表記を渡すべき所で数値(または逆)
・setValuesに1次元配列やサイズ不一致の2次元配列を渡した
・Utilities.formatDateやシートの日時演算にDateではなく文字列を渡した
・UrlFetchApp.fetchの第2引数に不正なオプション(文字列/配列)を渡した
・MailApp.sendEmailのオーバーロードを取り違え、型が合っていない
・JSON.parseにオブジェクトを渡している(文字列でない)
・CacheService.putの有効期限が範囲外(1〜600秒)
・Trigger作成APIに不正な関数名/対象/間隔を渡した
・Advanced Services(Sheets/Drive等)に仕様外のボディを渡した
ケース1:getRangeの指定ミス(A1表記 vs 行列指定)
// NG:行・列指定のつもりでA1文字列を渡している
const r = sheet.getRange('2', '3'); // Invalid argument
// OK:どちらかに統一
sheet.getRange('B2'); // A1表記
sheet.getRange(2, 2); // 行・列(1始まり)ケース2:setValuesは“2次元配列+サイズ一致”が必須
// NG:1次元配列
sheet.getRange(1,1,3,1).setValues(['a','b','c']); // Invalid argument
// OK:2次元に
sheet.getRange(1,1,3,1).setValues([['a'],['b'],['c']]);
// NG:サイズ不一致(範囲3x2に2x2)
sheet.getRange(1,1,3,2).setValues([['a','b'],['c','d']]); // Invalid argument
// OK:範囲と同じ3x2で渡す
sheet.getRange(1,1,3,2).setValues([['a','b'],['c','d'],['e','f']]);ケース3:Dateを期待する場所に文字列を渡している
// NG:formatDateの第1引数はDate型
Utilities.formatDate("2025-10-20", "Asia/Tokyo", "yyyy-MM-dd"); // Invalid argument
// OK
const d = new Date("2025-10-20T00:00:00+09:00");
Utilities.formatDate(d, "Asia/Tokyo", "yyyy-MM-dd");ケース4:UrlFetchApp.fetch / fetchAll のオプション型不整合
// NG:第2引数に文字列
UrlFetchApp.fetch('https://example.com', 'GET'); // Invalid argument
// OK:オプションはオブジェクト
UrlFetchApp.fetch('https://example.com', { method: 'get', muteHttpExceptions: true });
// NG:fetchAllは「リクエストオブジェクト配列」
UrlFetchApp.fetchAll(['https://a','https://b']); // Invalid argument
// OK
UrlFetchApp.fetchAll([{url:'https://a'},{url:'https://b'}]);ケース5:MailApp.sendEmailのオーバーロード取り違え
// 代表的OKパターン(シンプル版)
MailApp.sendEmail('user@example.com', '件名', '本文');
// オプション版(オブジェクトで渡す)
MailApp.sendEmail({
to: 'user@example.com',
subject: '件名',
htmlBody: '<b>本文</b>',
cc: 'cc@example.com'
});
// NG:件名にオブジェクト、本文に数値など
MailApp.sendEmail('user@example.com', {sub:'件名'}, 123); // Invalid argument
ケース6:JSON.parse/JSON.stringifyの引数型が不正
// NG:parseは“文字列”を期待
const obj = {a:1};
JSON.parse(obj); // Invalid argument
// OK
JSON.parse('{"a":1}');
// NG:stringifyはオブジェクト/配列を期待(循環参照に注意)
const circular = {}; circular.me = circular;
JSON.stringify(circular); // これは別の例外(循環参照)ケース7:CacheService.putの秒数範囲、キー/値の型
// NG:期限が600秒超
CacheService.getScriptCache().put('k', 'v', 1200); // Invalid argument
// OK:1〜600秒
CacheService.getScriptCache().put('k', 'v', 300);
// NG:キー/値にオブジェクト
CacheService.getScriptCache().put('k', {a:1}, 60); // Invalid argument
// OK:文字列化
CacheService.getScriptCache().put('k', JSON.stringify({a:1}), 60);
ケース8:Trigger作成APIの引数(関数名・対象・間隔)
// NG:存在しない関数名
ScriptApp.newTrigger('notExists').timeBased().everyMinutes(5).create(); // Invalid argument
// OK:実在する関数を指定
function job(){ /*...*/ }
ScriptApp.newTrigger('job').timeBased().everyMinutes(5).create();
// NG:スプレッドシート対象を未指定のままonEdit
ScriptApp.newTrigger('job').onEdit().create(); // Invalid argument
// OK:対象を明示
ScriptApp.newTrigger('job').forSpreadsheet(SpreadsheetApp.getActive()).onEdit().create();
ケース9:Advanced Sheets/Drive APIのボディ構造が仕様外
// NG:Values.updateのbodyは {values: 2次元配列}
Sheets.Spreadsheets.Values.update({ value: 'x' }, SHEET_ID, 'A1',
{ valueInputOption: 'RAW' }); // Invalid argument
// OK
Sheets.Spreadsheets.Values.update({ values: [['x']] }, SHEET_ID, 'A1',
{ valueInputOption: 'RAW' });ケース10:配列/オブジェクトAPIでのコールバック型ミス
// NG:Array.mapに関数以外
[1,2,3].map('x'); // Invalid argument
// OK
[1,2,3].map(n => n*2);入力検証のテンプレ(事前に“期待どおりか”を保証)
const V = {
is2D: (a) => Array.isArray(a) && a.every(r => Array.isArray(r)),
req: (cond, msg) => { if (!cond) throw new Error(msg); }
};
function safeSetValues(range, values) {
V.req(V.is2D(values), '2次元配列が必要です');
V.req(values.length > 0 && values[0].length > 0, '空配列は不可');
const r = range.getNumRows(), c = range.getNumColumns();
V.req(values.length === r && values[0].length === c, '範囲とサイズが一致しません');
range.setValues(values);
}診断のコツ(どの引数が不正かを素早く突き止める)
・例外行の直前でtypeof/Array.isArray/値のログを出す
・A1表記か数値指定かを呼び出しごとに統一する
・fetch/sendEmailは“どのオーバーロードを使うか”を明確にする
・Advanced Servicesは公式のサンプルに沿って最小ボディで通す→徐々に拡張
チェックリスト(上から順に潰す)
・引数の型は期待と一致しているか(string/number/boolean/Date/object/2次元配列)
・A1表記と行列指定を混ぜていないか
・setValuesは2次元+サイズ一致か
・fetch/sendEmailは正しいシグネチャを選んでいるか
・JSON.parseに“文字列”を渡しているか
・CacheServiceの期限は1〜600秒か、値は文字列か
・Trigger作成時に実在の関数名と適切なターゲットを指定しているか
・Advanced Servicesのリクエストボディは公式の型に沿っているか
-
前の記事
GAS『Trigger Already Exists』エラーの原因・対処まとめ 2025.10.20
-
次の記事
GAS『Cannot Find Method』の原因と対処法 2025.10.22
コメントを書く