GAS『Script Function Not Found』の原因と対処法
- 作成日 2025.10.10
- その他
Google Apps Scriptで「Script function not found: xxx」は、呼び出した関数名が実行時に見つからないときに出る。原因は関数名の不一致、グローバルで定義されていない、ウェブアプリのエントリ(doGet/doPost)未定義、トリガーやデプロイの参照先ずれ、保存漏れ・版ずれなど。発生場面ごとの直し方と再発防止のコツをまとめる。
目次
- 1. エラーの意味と主な発生場面
- 2. まず確認(最短チェック)
- 3. ケース1:関数名の不一致(タイポ・全角・大文字小文字)
- 4. ケース2:ウェブアプリの doGet/doPost が無い/旧デプロイを参照
- 5. ケース3:HTMLサービスの google.script.run でサーバ関数名不一致
- 6. ケース4:トリガー(シンプル/インストール型)が不正な関数名を指す
- 7. ケース5:グローバルで定義されていない(IIFE/ブロック/モジュール風)
- 8. ケース6:ライブラリ/clasp/別プロジェクトIDの版ずれ
- 9. ケース7:保存漏れ/構文エラーで最新が反映されていない
- 10. 迅速な切り分けユーティリティ(グローバル関数の見える化)
- 11. 通し例1:ウェブアプリ(doGet未定義→修正)
- 12. 通し例2:HTMLサービス(サーバ関数名ズレ→修正)
- 13. 通し例3:トリガー(改名後の指し替え)
- 14. 再発防止の運用ルール
- 15. 最終チェックリスト
エラーの意味と主な発生場面
・エディタの実行/Runメニューで指定した関数が存在しない
・ウェブアプリURLにアクセスしたが doGet/doPost が無い
・HTMLサービスの google.script.run で呼んだサーバ関数が無い
・シンプルトリガー(onOpen/onEditなど)の名前が不正
・インストール型トリガーが削除/改名済みの関数を指している
・ライブラリ/デプロイ(clasp含む)が古い版を参照しているまず確認(最短チェック)
□ 呼び出し名と定義名は完全一致か(大文字/小文字/全角無し)
□ 関数はトップレベル(グローバル)で定義されているか(IIFE/{} 内ではない)
□ 全ファイルを保存したか(⌘/Ctrl+S)/構文エラーが残っていないか
□ ウェブアプリは doGet/doPost を定義し、新バージョンでデプロイ済みか
□ トリガーが存在し、正しい関数名を指しているか(削除した関数名になっていないか)
□ ライブラリ/バージョン/スクリプトIDが想定のものかケース1:関数名の不一致(タイポ・全角・大文字小文字)
// NG:大文字小文字が違う
function myFunc() {}
function run() { myfunc(); } // Script function not found: myfunc
// OK:完全一致
function myFunc() {}
function run() { myFunc(); }
// NG:全角混入(見た目が似ていても別文字)
function doPost(e) {}
function test() { doPost({}); } // P が全角 → not found
// 対処:呼び出し箇所をコピペで置換、全角・空白を排除ケース2:ウェブアプリの doGet/doPost が無い/旧デプロイを参照
// NG:doGet 未定義でURLにアクセス → Script function not found: doGet
// OK:エントリを定義
function doGet(e) {
return HtmlService.createHtmlOutput('OK');
}
function doPost(e) {
return ContentService.createTextOutput('POST OK');
}
// 手順
// 1) 関数を定義 → 2) ファイル保存 → 3) 「新バージョンとしてデプロイ」→ 4) 最新URLで確認
・デプロイ更新を忘れると古いコードが動くため、新バージョンで公開し直す。
ケース3:HTMLサービスの google.script.run でサーバ関数名不一致
// Code.gs(サーバ)
function addRow(values) {
const sh = SpreadsheetApp.getActiveSheet();
sh.appendRow(values);
}
// index.html(クライアント)
<script>
function submit() {
const values = ['A','B','C'];
google.script.run
.withSuccessHandler(() => alert('done'))
.addRow(values); // ← addRow と完全一致
}
</script>
// NG例:.addrow と書く/IIFE内の関数を呼ぶ → not found・google.script.run から呼べるのは .gs のトップレベル関数のみ。
ケース4:トリガー(シンプル/インストール型)が不正な関数名を指す
// NG:シンプルトリガー名が誤り(onedit など)
function onedit(e) {} // 実行されず、期待動作にならない
// OK:正しい関数名
function onEdit(e) { /* ... */ }
// インストール型トリガーが古い関数名を指している場合の修正
function listTriggers() {
ScriptApp.getProjectTriggers().forEach(t =>
console.log(t.getHandlerFunction(), t.getEventType()));
}
function resetTrigger() {
// 古いトリガーを削除して再作成
ScriptApp.getProjectTriggers().forEach(t => ScriptApp.deleteTrigger(t));
ScriptApp.newTrigger('batchJob').timeBased().everyMinutes(5).create();
}
function batchJob() { /* 本処理 */ }・関数を改名/削除したら、紐づくトリガーも更新する。
ケース5:グローバルで定義されていない(IIFE/ブロック/モジュール風)
// NG:IIFEの内側 → グローバルから見えない
(() => {
function hidden() {}
})();
function run() { hidden(); } // not found
// OK:トップレベル関数として定義
function visible() {}
function run() { visible(); }
// NG:ブロックスコープ内
{
function localOnly() {}
}
function run2() { localOnly(); } // not found・Apps Scriptで呼び出し対象はトップレベルに置く。
ケース6:ライブラリ/clasp/別プロジェクトIDの版ずれ
// 診断:実行中プロジェクトのスクリプトIDを確認
function whoAmI() {
console.log('scriptId:', ScriptApp.getScriptId());
}
// 対処の方針
// ・ライブラリ:プロジェクト設定→ライブラリ→参照バージョンを最新に
// ・ウェブアプリ:新バージョンとしてデプロイ(URLは同じでも中身は更新が必要)
// ・clasp:push 後にエディタで反映を確認、必要なら再デプロイ・「あるはずの関数」が古い版には無いケースが典型。
ケース7:保存漏れ/構文エラーで最新が反映されていない
// 1) すべてのタブを保存(⌘/Ctrl+S)
// 2) エディタの問題タブ/コンソールで構文エラーがないか確認
// 3) 実行ログ(Executions)で失敗原因を確認・保存できていないファイルが1つでもあると、実行時に旧コードが走ることがある。
迅速な切り分けユーティリティ(グローバル関数の見える化)
function listGlobals() {
const names = Object.keys(this).filter(k => typeof this[k] === 'function');
names.sort();
console.log(names.join(', ')); // ここに呼びたい関数名が出ているか確認
}
function assertFunction(name) {
if (typeof this[name] !== 'function') {
throw new Error('関数が見つかりません: ' + name);
}
}・not found が出る名称と、この一覧の差を埋めると早い。
通し例1:ウェブアプリ(doGet未定義→修正)
// NG
// (doGetが無い状態でURLアクセス)→ Script function not found: doGet
// OK
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('index');
}通し例2:HTMLサービス(サーバ関数名ズレ→修正)
// Code.gs(OK版)
function saveRow(v) {
SpreadsheetApp.getActiveSheet().appendRow(v);
}
// index.html(OK版)
<script>
function send() {
google.script.run.withSuccessHandler(() => alert('saved')).saveRow(['a','b']);
}
</script>通し例3:トリガー(改名後の指し替え)
// 旧:function job() {}
// 新:function batchJob() {}
// → 旧トリガーは 'job' を指し続けるので not found
function migrateTrigger() {
ScriptApp.getProjectTriggers().forEach(t => ScriptApp.deleteTrigger(t));
ScriptApp.newTrigger('batchJob').timeBased().everyMinutes(10).create();
}再発防止の運用ルール
・エントリポイント(doGet/doPost/onEdit/onOpen/バッチ関数)は1ファイルに集約
・改名時は「検索置換 → トリガー再作成 → 新バージョンで再デプロイ」をセット運用
・google.script.run で呼ぶ関数は .gs のトップレベルのみを約束
・レビュー時に listGlobals() の出力で存在確認
・clasp/ライブラリは参照バージョンとスクリプトIDをREADMEに明記最終チェックリスト
□ 呼び出し名=定義名が完全一致(大/小/全角なし)
□ トップレベル関数として定義(IIFE/ブロック外)
□ すべて保存済み、構文エラーなし
□ ウェブアプリの doGet/doPost を定義して「新バージョンでデプロイ」
□ トリガーが正しい関数名を指している(不要なものは削除)
□ ライブラリ/デプロイの参照バージョンが最新
□ listGlobals() に目的の関数名が現れる-
前の記事
GAS『Exceeded Maximum Execution Time』の原因と対処法 2025.10.09
-
次の記事
GAS『Cannot Call Method on Null』の原因と対処法 2025.10.14
コメントを書く