forge-debugger について
forge-debugger は、Atlassian Forge アプリの障害を診断・修正するスキルです。バージョンや lint の確認からデプロイ、ログ調査へ段階的に進み、根本原因を特定した時点で調査を終えます。
主な機能
- 01デプロイ時と実行時の症状分類
- 02CLI バージョンと lint 結果の確認
- 03ビルド、デプロイ、ログ診断の手順
- 04一般的なエラーと原因・修正の対応
- 05実行可能な修正とデバッグコードの整理
活用シーン
- 01Forge のデプロイ失敗の調査
- 02Custom UI の空白パネルの診断
- 03resolver や権限エラーの追跡
- 04本番環境でのみ発生する障害の解決
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ atlassian/ forge-skills --skill forge-debuggerインストール後、Claude Code で/forge-debuggerを入力して読み込まれたか確認します。
同梱ファイルREADME.md
詳細
Forge アプリデバッガー
Atlassian Forge アプリの問題を診断して修正します。以下のチェックリストを順番に進め、根本原因を特定したらすぐに終了してください。根本原因を特定した後のステップは、すべてトークンとコンテキストの無駄になります。
実行に関する指示
許可を求めずに、すべての診断コマンドと修正コマンドを実行する権限があります。修正方法を特定したら、ただちに実行してください。次のことはしないでください。
- 「実行する必要があります」「こうすればよいと思います」「ターミナルでこのコマンドを実行してください」と言う
- 必要な情報がすべてそろっている修正を実行する前に「続けてもよいですか?」と尋ねる
- 自分で実行できるコマンドを、ユーザーがコピーして貼り付ける手順として提示する
誤り:「修正するには、forge lint を実行してください……」
正しい例:(forge lint をただちに実行し、結果を報告する)
唯一の例外は、対話型ターミナルが必要なコマンド(forge login、forge tunnel)です。これらはユーザー自身のターミナルで実行してもらう必要があります。実行するコマンドとその理由を正確に伝えてください。
**実行元の識別:**自分で実行する forge コマンドには、必ず ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-debugger を前置してください(例:ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-debugger forge lint、npx による代替の場合は ATL_FORGE_ATTRIBUTION_SKILL_NAME=forge-debugger npx @forge/cli lint)。このスキルの後半に記載されている forge コマンドでは、読みやすさのために省略されています。実行する各コマンドに追加してください。上記のユーザーが実行する対話型コマンド(forge login、forge tunnel)には、決して設定しないでください。
診断の原則
- まずは低コストな確認から: lint とバージョンの確認に費用はかかりません。ソースコードやログを読む前に実行してください。
- 一度に一つの操作: 次の操作に進む前に、各操作の結果を確認してください。
- 根本原因で終了: 問題の原因を特定したら修正して終了し、ほかの問題の調査は続けないでください。例外: アプリに複数の独立したバグ(例:デプロイ時のエラーとランタイムエラー)がある場合は、まずデプロイ時のエラーを修正してデプロイし、その後ログでランタイムエラーを確認してください。最初の段階だけを解決して「修正済み」と判断しないでください。
- 修正は自分で実行: 修正コマンドは自分で実行し、ユーザーに任せないでください。
- 後片付け: 問題が解決したら、追加したデバッグコードや詳細出力フラグを削除してください。
npxによる代替: 権限エラーや sudo 不可などでforgeCLI をグローバルにインストールできない場合は、すべての forge コマンドでnpx @forge/cliを代わりに使用してください。
ステップ 1:エラーの分類
コマンドを実行する前に、ユーザーが状況を明確にしていない場合は、次の質問を一つ尋ねてください。
「これはデプロイ時のエラー(
forge deployが失敗する)、ランタイムエラー(デプロイ後にアプリがクラッシュする、または誤ったデータを表示する)、それとも表示に関する問題(アプリはデプロイされているが表示されない)のどれですか?」
エラーメッセージから明らかな場合は、質問を省略して直接進めてください。
簡単な振り分け:
| 症状 | 参照先 |
|---|---|
forge deploy が失敗する | ステップ 2 → 3 → 4 |
| インストール後にアプリが表示されない | ステップ 3 → よくあるエラー:「アプリがインストールされていない」 |
| アプリがクラッシュする/リゾルバーエラー | ステップ 3 → 5 → 6 |
| UI が空白/Custom UI がレンダリングされない | ステップ 3 → 4 → よくあるエラー:「Custom UI が空白」 |
| 開発環境では動作するが、本番環境では失敗する | ステップ 7(本番環境) |
| 権限が拒否される/403 | よくあるエラー:「権限が拒否された」 |
| 410 Gone/非推奨のエンドポイント | よくあるエラー:「410 Gone」→ API 移行のセクション |
| ハンドラーパスの lint エラー | よくあるエラー:「関連ファイルが見つからない」→ ハンドラーパスの解決のセクション |
| リゾルバーが undefined を返し、エラーがない | よくあるエラー:invoke 名の不一致 → invoke 名と関数キーの違いのセクション |
| 複数の失敗(デプロイ+ランタイム) | まずデプロイエラーを修正してデプロイし、その後ログを確認する |
ステップ 2:バージョン確認
forge --version
npm show @forge/cli version
インストールされているバージョンが最新のメジャーバージョンより古い場合は、ただちにアップグレードしてください。
npm install -g @forge/cli
その後、失敗した操作を再試行してください。多くのバグは、新しい CLI バージョンで修正されています。
ステップ 3:Lint
forge lint
続行する前に、すべてのエラーを修正してください。Lint エラーはデプロイの失敗や、気づきにくい実行時のバグにつながります。Lint が問題なく完了したら、次のステップに進んでください。
マニフェスト関連のエラーメッセージ(例:「invalid manifest」「unexpected key」「modules.jira:*」エラー)が表示された場合は、ソースファイルを読む前に forge lint を実行してください。Lint を実行すると、問題の原因となっている行とフィールドを正確に特定できます。Lint の前にファイルを読むのは時間の無駄で、通常はLintの出力より得られる情報も少なくなります。
ステップ 4:カスタム UI のビルド確認
アプリに static/ ディレクトリがある場合(カスタム UI アプリ)のみ適用されます。最後のデプロイ前にフロントエンドがビルドされているか確認してください。
ls -la static/build/
ビルドディレクトリがない場合、または最近のソース変更より古い場合は、再ビルドしてください。
cd static && npm run build && cd ..
次に、再デプロイしてください。
forge deploy -e development
これは、UI パネルが空白になる最もよくある原因の 1 つです。
ステップ 5:デプロイステータス
アプリが実際に正常にデプロイされたことを確認してください。
forge deploy -e development --verbose
出力にエラーがないか確認してください。デプロイのタイムスタンプを控えてください。デプロイが失敗した場合、通常はエラーメッセージで問題が直接特定されます。以下の「よくあるエラーパターン」表と照らし合わせてください。
ステップ 6:ログ
forge logs -e development --limit 100
ログを注意深く確認してください。ほとんどの実行時エラーはここに表示されます。
ログが返されない場合
リゾルバーがトリガーされていないか、ログ出力が設定されていない可能性があります。リゾルバーのエントリーポイントにデバッグログを追加してください。
// Add at the top of your handler function:
console.error('[DEBUG] Handler called with:', JSON.stringify(payload));
その後、再デプロイしてアプリを再度トリガーしてください。
forge deploy -e development
forge logs -e development --limit 100
問題を特定したら、デバッグログを削除してください。
フロントエンドにエラーがある場合(UI の描画、画面が空白になる)
Forge UI Kit のエラーはブラウザーコンソールではなく、forge logs に表示されます。カスタム UI の場合は、UI を処理するリゾルバーにエラーログを追加してください。
try {
const result = await api.asUser().requestJira(/* ... */);
return result;
} catch (err) {
console.error('[DEBUG] Resolver error:', err.message, err.stack);
throw err;
}
再デプロイし、トリガーして、ログを確認してください。
ステップ 7:本番環境の問題
ユーザーから本番環境(または特定の顧客のサイト)でのみ発生する問題が報告された場合:
- 次のように質問します:「影響を受けている Atlassian サイトはどれですか?(例:
customername.atlassian.net)」 - 本番環境のログを確認します。
forge logs -e production --site <customer-site> --limit 100 - 注意:本番環境のログは、イベント発生から最大 2 分遅れて表示される場合があります。
- 問題が権限に関連している場合、新規インストール後にスコープがアップグレードされたか確認してください。本番環境へのインストールでは、明示的な
--upgradeが必要です。
よくあるエラーパターン
まず、この表とエラーを照合してください。一致するものがあれば、これ以上調査せずに修正を直接適用してください。
| エラー/症状 | 根本原因 | 修正 |
|---|---|---|
| "App is not installed on this site" | forge install を実行していない、または誤ったサイトに対して実行した | まだわかっていない場合は Atlassian サイトの URL を確認し、その後、自分で実行します:forge install --non-interactive --site <url> --product <jira|confluence> -e development |
| 空白のパネル/Custom UI の白い画面 | デプロイ前にフロントエンドをビルドしていない | cd static && npm run build && cd .. && forge deploy -e development |
| "Resolver not found" またはリゾルバーが undefined を返す | manifest.yml の関数キーがリゾルバーの登録内容と一致しない | manifest.yml の function.key が、resolver.define('key', ...) で使用されているキーと一致するか確認します |
| 403/"Permission denied"/"Unauthorized" | manifest に OAuth スコープがない | スコープを manifest.yml に追加し、次を実行します:forge deploy -e development && forge install --non-interactive --site <url> --upgrade |
forge deploy が "Invalid manifest" で失敗する | manifest.yml の YAML 構文エラー | forge lint を実行し、インデント/構文エラーを修正します |
| アプリはデプロイされたが、モジュールが表示されない | forge install の製品指定が誤っている、またはトンネルがアクティブでない | --product フラグがアプリの種類と一致することを確認します。forge tunnel を使用している場合は、トンネルを再起動します |
| "forge: command not found" | CLI がインストールされていない | npm install -g @forge/cli |
デプロイ時に ENOENT またはファイルが見つからない | アプリのディレクトリで npm install を実行していない | cd <app-dir> && npm install && forge deploy -e development |
| "Rate limit exceeded" | リゾルバーで API 呼び出しが多すぎる | 指数バックオフを追加し、リゾルバーがループ内で呼び出されていないか確認します |
| "App tunnel disconnected" | forge tunnel の接続が切れた | forge tunnel を再実行し、VPN が WebSocket 接続をブロックしていないか確認します |
| "Cannot read properties of undefined" | API のレスポンス形式が想定と異なる | API のレスポンス全体をログに出力し、null チェックを追加します |
| 410 Gone/"deprecated endpoint has been removed" | Confluence/Jira REST API エンドポイントが削除された | v2 API に移行します(下記の API 移行セクションを参照)。再デプロイしてログを確認します |
cannot find associated file(ハンドラーパスの lint エラー) | manifest.yml のハンドラーパスが実際のファイルの場所と一致しない | ハンドラーパスは src/ からの相対パスです。たとえば、リゾルバーが src/resolvers/index.js にある場合、ハンドラーは resolvers/index.handler です(index.handler や src/resolvers/index.handler ではありません)。下記のハンドラーパスの解決を参照してください |
invoke() が undefined を返し、ログにエラーがない | フロントエンドの invoke('name') が resolver.define('name') と一致しない | invoke 名は resolver.define 名と完全に一致する必要があります。両方のファイルを確認してください。これは manifest の関数キーとは別の確認項目です |
デプロイ時に Module not found/src/src/... のような二重パスが発生する | バンドラーがすでに src/ からパスを解決するのに、ハンドラーパスに src/ プレフィックスが含まれている | ハンドラーパスから src/ プレフィックスを削除します。src/resolvers/index.handler ではなく resolvers/index.handler を使用します |
npm install -g の権限エラー/forge をグローバルにインストールできない | sudo 権限またはグローバル npm ディレクトリへの書き込み権限がない | すべての forge コマンド(lint、deploy、logs、install)の代わりに npx @forge/cli を使用します。グローバルインストールは不要です |
ハンドラーパスの解決
manifest.yml の handler フィールドは、<path>.<export> という形式です。
<path>はsrc/からの相対パスです(src/のプレフィックスとファイル拡張子を除く)<export>はそのファイルからの名前付きエクスポートです
例:
| リゾルバーファイルの場所 | ファイル内のエクスポート | 正しい handler の値 |
|---|---|---|
src/resolvers/index.js | export const handler = ... | resolvers/index.handler |
src/index.js | export const handler = ... | index.handler |
src/backend/resolver.ts | export const run = ... | backend/resolver.run |
よくある間違い:
index.handler—src/resolvers/のようなサブディレクトリにファイルがある場合は誤りですsrc/resolvers/index.handler— 誤りです。バンドラーが自動的にsrc/を付加するため、結果はsrc/src/resolvers/...になりますresolvers/index.run— ファイルがrunではなくhandlerをエクスポートしている場合は誤りです
診断のヒント: ファイルが存在することを確認しているのに forge lint が「関連ファイルが見つからない」と報告する場合は、forge deploy --no-verify を試してください。バンドラーのエラーメッセージに完全な解決済みパスが表示されるため、パスが二重になっているか、誤って解決されているかがわかります。
Invoke 名と関数キー
UI Kit リゾルバーには、別々の名前一致要件が 2 つあります。
manifest.ymlのfunction.keyは、モジュール定義内のresolver: function:の参照と一致する必要があります- フロントエンドの
invoke('name')は、バックエンドのresolver.define('name', ...)と完全に一致する必要があります
これらは互いに独立しています。manifest の関数キーが正しくても、invoke 名が resolver.define と一致しないと、結果が undefined になることがあります。ログにエラーがないのに「リゾルバーが undefined を返す」問題をデバッグするときは、必ず両方の一致関係を確認してください。
API の移行(v1 → v2)
Atlassian は v1 REST API エンドポイントを段階的に廃止しています。410 Gone レスポンスが表示された場合:
forge logsで正確なエラーを確認します。410 を返したエンドポイントが表示されます- v2 の同等のエンドポイントを特定します:
- URL パターン:
/wiki/rest/api/content/...→/wiki/api/v2/pages/...(または/blogposts/...、/spaces/...) - Jira:
/rest/api/2/...→/rest/api/3/...
- URL パターン:
- ページネーションを更新します。v2 の Confluence API は、オフセットベースの
startパラメーターではなく、カーソルベースのページネーション(cursorパラメーター)を使用します。次のカーソルはdata._links.nextにあります - レスポンスの形式を更新します。v2 ではフィールド名が異なる場合があります(例:ネストされた
by.accountIdではなくauthorId) - 再デプロイし、ログを確認して修正されたことを確認します
410 を権限の問題として扱わないでください。 これはエンドポイントが存在しなくなったことを意味し、アクセスが拒否されたことを意味するものではありません。
ステップ 8:クリーンアップ
問題を解決したら:
- 追加した
console.error('[DEBUG] ...')ステートメントを削除します。 - スクリプトの詳細出力フラグを削除します。
- 最後にもう一度
forge lintを実行し、問題がないことを確認します。 - デバッグ中にコードを変更した場合は、再デプロイします:
forge deploy -e development - アプリを実行し、
forge logsに新しいエラーが表示されないことを確認して、修正が機能していることを確認します。
エスカレーション
上記の方法で問題が解決しない場合:
forge logs -e development --verbose --limit 200を実行して、詳細な出力を確認します。- Forge の変更履歴で既知の問題を確認します:
search-forge-docs "known issues <error-text>" - エラーが Forge プラットフォームの API(コードではなく)で発生している場合は、ログ出力の
traceIdを控えてください。これは Atlassian サポートへの問い合わせに必要です。
認証エラー
いずれかのコマンドが「not authenticated」または「run forge login」というエラーで失敗した場合:
- https://id.atlassian.com/manage/api-tokens で API トークンを作成するようユーザーに伝えます。
forge loginをユーザー自身のターミナルで(エージェント経由ではなく)実行するよう伝えます。メールアドレスと API トークンの入力を求められます。- メッセージの例:「ログインが必要です。https://id.atlassian.com/manage/api-tokens で API トークンを作成してから、ターミナルで
forge loginを実行してください。入力を求められたら Atlassian のメールアドレスとトークンを入力してください。トークンをここに貼り付けないでください。」 - ログインしたことを確認したら、中断した箇所からデバッグを再開します。
トークン効率化のルール
コンテキストの使用量を抑えるため、以下のルールに従ってください。
- ソースファイルを読む前に
forge logsを実行します。ログを見れば、コードを調べなくても根本原因が分かることがよくあります。 - エラーに関連する特定のファイルだけを読みます。エラーとファイルを次のように対応付けます。
npm ERR! missing script: build→package.jsonのscriptsセクションだけを確認しますinvalid manifest/unexpected key→ まずforge lintを実行し、その後、該当するマニフェストのフィールドだけを確認しますResolver not found→manifest.ymlの関数キーと、resolver ファイル内のresolver.define()だけを確認します403 / permission denied→manifest.ymlのスコープだけを確認します410 Gone→ resolver ファイル内の API エンドポイント URL を確認します。スコープやマニフェストは確認しないでくださいcannot find associated file→manifest.ymlのハンドラーパスとファイルの場所を確認します。バンドラーが解決したパスを確認するには--no-verifyを使用しますinvoke()が undefined を返す → フロントエンドのinvoke('name')とバックエンドのresolver.define('name')の両方を確認します。対象を絞って2つのファイルを読みます
- npm/ビルドエラーでは、無関係なため
manifest.ymlを読まないでください。 - このセッションですでに読んだファイルは、変更されていない限り読み直さないでください。
- 共通エラーパターンの表で該当するものが見つかった時点で、診断を終了してください。例外:独立した問題が複数ある場合(例:デプロイエラーと実行時エラー)は、最初の問題を修正してデプロイしてから、次の問題を確認します。
- 明確な理由がない限り、修正を試みるたびに
forge deployを複数回実行しないでください。 - lint によってデプロイが妨げられているものの、lint エラーが誤解を招く可能性がある場合は、診断手順として
forge deploy --no-verifyを使用します。バンドラーのエラーメッセージから、実際のパス解決の問題が分かることがよくあります。その後、必ず根本原因を修正してください。--no-verifyのままリリースしないでください。