- 技術 💻
バグ報告の書き方|コピペ用テンプレートと重大度判定表
バグ報告(バグレポート・不具合報告)とは、「何をしたら、何が起きて、本当はどうなるはずだったか」を、直す人がそのまま再現できる形で伝える文書です。良い報告の条件は、再現手順・期待と実際・環境・証跡・影響範囲・頻度の6つがそろっていること。この6つがそろうと、開発者は質問の往復なしに調査へ入れます。
この記事では、コピペで使えるMarkdownテンプレートと記入例、GitHub Issue FormsのYAML、Jira・Backlogへの項目対応表に加えて、上位の解説記事にはない重大度(S1〜S4)と優先度(P1〜P4)の判定表、同じバグの「伝わらない例→伝わる例」、ブラウザのコンソール・HAR・サーバーログ・リクエストIDといった証跡の取り方を実際に取得した出力つきで解説します。なお、当サイトの「障害報告書の書き方」は起きた障害を関係者に説明する報告書の記事で、本記事は直してもらうために開発者へ渡す報告の書き方です。
良いバグ報告の早見表
| 項目 | 書くこと | 書き方の例 | 抜けると起きること |
|---|---|---|---|
| タイトル | 「どこで・何をすると・どうなる」を1行で | タスク編集画面で保存すると「保存しました: 」の後が空になり、保存されない | 一覧で見分けがつかず、重複報告が増える |
| 再現手順 | 番号つき・最短・前提データつき | 1. 会員 sato で 2. タスク #42 を開く 3. タイトルを変えて保存 | 開発者が再現できず、「詳細を教えてください」から始まる |
| 期待と実際 | 「本当はこうなるはず」と「実際はこう」を分けて | 期待:保存されて一覧に反映 / 実際:エラー表示のまま更新されない | 仕様どおりなのかバグなのかが判断できない |
| 環境 | OS・ブラウザとバージョン、アプリのバージョン、環境(本番/検証)、アカウント種別 | Windows 11 / Chrome 141 / v2.4.0 / ステージング / 一般会員 | 特定環境でしか起きないバグの切り分けに時間がかかる |
| 証跡 | スクリーンショット・動画、コンソールのエラー、失敗した通信(HAR)、ログの抜粋、リクエストID | PUT /api/tasks/42 -> 500, X-Request-Id: 9d64… |
ログの山から該当箇所を探すところから始まる |
| 影響範囲 | 誰が・どの機能で・どのくらい困るか、回避策の有無 | タイトル変更をする全会員。回避策:新規作成して古い方を削除 | 優先度が決められず、後回しか過剰対応になる |
| 頻度 | 常に/条件つき/断続的(n回中m回) | 10回中10回。タイトルに日本語を含むときのみ | 「再現しない」で閉じられる |
| 重大度・優先度 | 判定表(本記事)に沿って初期値を提案 | S2 / P2 | トリアージのたびに議論が発生する |
| 発生日時・ID | 分単位の日時(タイムゾーン)、対象データのID | 2026-09-30 15:07 JST、タスク #42 | ログと突き合わせられない |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「バグ報告の書き方|コピペ用テンプレートと重大度判定表」
コピペ用テンプレート(Markdown)
まずはこのテンプレートを、チームのIssue・チケット・チャットにそのまま貼って使ってください。見出しはそのままに、書けない項目は「不明」と書いて残すのがコツです(消してしまうと「聞き忘れた」のか「該当なし」なのかが分からなくなります)。
## タイトル
(どこで・何をすると・どうなる)
## 環境
- 環境:本番 / ステージング / ローカル
- アプリのバージョン・ビルド:
- OS / ブラウザ・バージョン:
- 端末・画面幅:
- アカウント・権限:
- 発生日時(タイムゾーン):
- 対象データのID:
## 再現手順
1.
2.
3.
## 期待した結果
(本来こうなるはず。根拠:仕様書 / これまでの動き / 他画面との整合)
## 実際の結果
(画面に出たメッセージはそのまま貼る)
## 頻度
常に / 条件つき(条件: ) / 断続的( 回中 回)
## 影響範囲と回避策
- 影響:誰が・どの機能で・どのくらい困るか
- 回避策:あり(方法: ) / なし
## 証跡
- スクリーンショット / 動画:
- コンソールのエラー:
- 失敗した通信(メソッド・URL・ステータス・リクエストID):
- ログの抜粋:
## 重大度 / 優先度(提案)
S / P (理由: )
## 補足
(直前にやったこと、関連しそうな変更、似た報告へのリンク)
記入例(架空の会員制タスク管理サービス)
この記事で実際に再現させたバグを、テンプレートに沿って書いた例です。証跡の値は、後述の手順で実際に取得したものをそのまま使っています。
## タイトル
タスク編集画面で「保存」を押すとメッセージが空のまま止まり、タイトルが保存されない
## 環境
- 環境:ステージング
- アプリのバージョン・ビルド:v2.4.0(コミット 3f1c9e2)
- OS / ブラウザ・バージョン:Linux / Chrome 141.0.7390.37
- 端末・画面幅:PC / 1000px
- アカウント・権限:一般会員(sato@example.com)
- 発生日時(タイムゾーン):2026-09-30 15:07 UTC(10-01 00:07 JST)
- 対象データのID:タスク #42
## 再現手順
1. 一般会員でログインし、タスク一覧から「#42 週次レポート作成」を開く
2. タイトル欄を「週次レポート作成(10月分)」に変える
3. 「保存」ボタンを押す
## 期待した結果
「保存しました: 週次レポート作成(10月分)」と表示され、一覧に新しいタイトルが反映される
(根拠:他のタスクでは同じ操作で保存できていた)
## 実際の結果
画面には何も表示されず、一覧のタイトルも変わらない。ブラウザのコンソールに
「Cannot read properties of undefined (reading 'title')」が出る
## 頻度
常に(10回中10回)。タイトルを変えない保存でも発生する
## 影響範囲と回避策
- 影響:タスクのタイトルを変更したい全会員。作成・削除は問題なし
- 回避策:あり(新しいタスクを作り直し、古い方を削除する)
## 証跡
- スクリーンショット:screenshot.png(保存直後の画面)
- コンソールのエラー:
[console.error] Failed to load resource: the server responded with a status of 500 (Internal Server Error)
[pageerror] Cannot read properties of undefined (reading 'title')
- 失敗した通信:PUT /api/tasks/42 -> 500
X-Request-Id: 9d64991d-7c69-41c3-bd70-360b3c56710d
応答本文:{"error":"internal_error","request_id":"9d64991d-7c69-41c3-bd70-360b3c56710d"}
- ログの抜粋(request_id で検索):
{"time":"2026-09-30T15:07:31.175Z","level":"error","path":"/api/tasks/42",
"msg":"column \"titel\" of relation \"tasks\" does not exist"}
## 重大度 / 優先度(提案)
S2 / P2(理由:主要機能の一部が全会員で使えないが、回避策はある)
## 補足
- 9/30 のリリース(v2.4.0)以降に発生。v2.3.0 では保存できていた
- サーバー側のエラーに "titel" という綴りがあり、更新SQLの列名が原因の可能性
GitHub Issue Forms のYAMLテンプレート
GitHubでは、リポジトリの .github/ISSUE_TEMPLATE/ にYAMLを置くと、入力欄つきのフォームでバグ報告を受け付けられます。必須項目を validations: required: true にしておくと、再現手順や環境の抜けをフォームの段階で防げます。以下は上のMarkdownテンプレートをフォーム化したもので、.github/ISSUE_TEMPLATE/bug_report.yml として保存します(公式ドキュメント「Syntax for issue forms」の構文に沿っています)。
name: バグ報告
description: 不具合を報告する(再現手順・期待と実際・環境・証跡)
title: "[Bug]: "
labels: ["bug", "triage"]
body:
- type: markdown
attributes:
value: |
報告ありがとうございます。再現手順と証跡があると調査がすぐ始められます。
- type: dropdown
id: env
attributes:
label: 環境
options:
- 本番
- ステージング
- ローカル
validations:
required: true
- type: input
id: version
attributes:
label: アプリのバージョン・ビルド
placeholder: "例: v2.4.0 / コミット 3f1c9e2"
validations:
required: true
- type: input
id: browser
attributes:
label: OS / ブラウザ・バージョン
placeholder: "例: Windows 11 / Chrome 141"
validations:
required: true
- type: textarea
id: steps
attributes:
label: 再現手順
description: 番号つきで、前提データ(アカウント・ID)も書いてください
value: |
1.
2.
3.
validations:
required: true
- type: textarea
id: expected
attributes:
label: 期待した結果
validations:
required: true
- type: textarea
id: actual
attributes:
label: 実際の結果
description: 画面のメッセージはそのまま貼ってください
validations:
required: true
- type: dropdown
id: frequency
attributes:
label: 頻度
options:
- 常に
- 条件つき
- 断続的
validations:
required: true
- type: textarea
id: logs
attributes:
label: コンソール・ログ・失敗した通信
description: 自動でコードブロックになります(バッククォート不要)
render: shell
- type: dropdown
id: severity
attributes:
label: 重大度(提案)
options:
- S1 致命的
- S2 重大
- S3 中
- S4 軽微
- type: checkboxes
id: checks
attributes:
label: 報告前の確認
options:
- label: 同じ報告がないか検索した
required: true
- label: 個人情報・トークンをマスクした
required: true
| 要素タイプ | 用途 | よく使う attributes |
|---|---|---|
markdown |
案内文(入力欄にならない) | value |
input |
1行の入力 | label description placeholder value |
textarea |
複数行の入力 | 上に加えて render(shell などを指定すると自動でコードブロック化) |
dropdown |
選択肢 | options multiple default(既定の選択肢の番号) |
checkboxes |
確認事項 | options(各項目に label と required) |
upload |
ファイル添付 | label description(公式ドキュメントの例にある新しい要素) |
注意点は3つです。①name description body の3つは必須。②各要素の id は英数字・ハイフン・アンダースコアだけ。③公式ドキュメントによると required の検証はパブリックリポジトリでのみ働くため、プライベートリポジトリでは案内文で補います。
Jira・Backlogへの項目対応表
ツールが違っても、書く中身は同じです。テンプレートの項目を、各ツールのどのフィールドに入れるかの対応表です(Jiraは企業管理プロジェクトの一般的なフィールド、Backlogは公式ヘルプ「課題の属性」に沿っています)。
| テンプレートの項目 | GitHub Issue | Jira | Backlog |
|---|---|---|---|
| タイトル | Title | Summary(要約) | 件名 |
| 種別 | Label bug / Type |
Issue Type = Bug | 種別 = バグ |
| 環境 | フォームの入力欄 | Environment(環境)または Description | 詳細(発生バージョンは「発生バージョン」欄) |
| 再現手順・期待・実際 | 本文 | Description | 詳細 |
| 証跡 | 本文への貼り付け・添付 | Attachment(添付) | 添付ファイル |
| 重大度 | Label(S1〜S4)またはカスタムフィールド |
Severity(カスタムフィールド) | カスタム属性 |
| 優先度 | Label(P1〜P4) |
Priority(Highest / High / Medium / Low / Lowest) | 優先度(高 / 中 / 低) |
| 影響バージョン | Milestone | Affects versions | 発生バージョン |
| 修正予定 | Milestone | Fix versions | マイルストーン |
| 担当 | Assignee | Assignee | 担当者 |
| クローズ理由 | Close as completed / not planned | Resolution | 完了理由(対応済み / 対応しない / 無効 / 重複 / 再現しない) |
重大度(S1〜S4)と優先度(P1〜P4)の判定表
重大度は「起きている事実の重さ」、優先度は「いつ直すかの判断」です。報告者は事実に基づいて重大度と、その初期値としての優先度を提案し、最終的な優先度はトリアージで決めます。この分け方にしておくと、「軽微だけど明日のイベント前に直したい」「重大だけど利用者がまだいない機能」といった状況を表現できます。
重大度の判定表
| 重大度 | 定義 | 例 | 目安 |
|---|---|---|---|
| S1 致命的 | 主要機能が使えない、データが失われる・壊れる、情報が守られない | ログインできない、保存したタスクが消える、他人のタスクが見える | 回避策がなく、全員に影響 |
| S2 重大 | 主要機能の一部が使えない、または多くの利用者に影響 | タイトル変更ができない、通知メールが届かない | 回避策はあるが手間がかかる |
| S3 中 | 機能は使えるが結果が一部誤る、限られた条件で発生 | 期限が過ぎたタスクの並び順が違う、特定の文字で検索できない | 回避策が簡単にある |
| S4 軽微 | 表示崩れ、誤字、使い勝手 | ボタンの位置ずれ、ヘルプ文の誤字 | 業務に支障がない |
優先度の判定表
| 優先度 | 対応の目安 | 判断のポイント |
|---|---|---|
| P1 即時 | 他の作業を止めて対応開始。修正版を臨時リリース | 影響人数が多い、回避策がない、期日が迫っている |
| P2 高 | 次のリリース(今の反復)に必ず含める | 主要機能に関わる、影響人数が中程度 |
| P3 中 | 計画に入れて順番に対応 | 回避策がある、影響が限定的 |
| P4 低 | 余裕があるときに、まとめて対応 | 見た目・文言、利用者がほぼ気づかない |
重大度と発生条件の組み合わせ表(優先度の初期値)
| 重大度\発生条件 | 常に | 条件つき | 断続的・まれ |
|---|---|---|---|
| S1 致命的 | P1 | P1 | P2 |
| S2 重大 | P1〜P2 | P2 | P3 |
| S3 中 | P2〜P3 | P3 | P3〜P4 |
| S4 軽微 | P3〜P4 | P4 | P4 |
表の値を上下させる要因は、「影響を受ける人数」「回避策の有無と手間」「期日(イベントや締め切り)」「発生してからの経過時間」の4つです。たとえば S4 の誤字でも、明日の説明会で映す画面なら P2 に上げる、といった判断をトリアージで行います。
同じバグを「伝わらない例」と「伝わる例」で書き比べ
伝わらない報告は、読んだ人が最初にやることが「質問」になります。伝わる報告は、最初にやることが「再現」になります。
| 観点 | 伝わらない例 | 伝わる例 |
|---|---|---|
| タイトル | 保存できません | タスク編集画面で「保存」を押すと保存されず、コンソールに TypeError が出る |
| 手順 | 保存ボタンを押すとエラーになります | 1. 一般会員でログイン 2. タスク #42 を開く 3. タイトルを変えて「保存」 |
| 期待と実際 | (書いていない) | 期待:保存されて一覧に反映 / 実際:画面が変わらず、通信は 500 |
| 環境 | (書いていない) | ステージング v2.4.0 / Chrome 141 / 一般会員 |
| 証跡 | 「エラーが出ます」 | PUT /api/tasks/42 -> 500、X-Request-Id: 9d64991d-…、コンソールの全文 |
| 影響・頻度 | 「急ぎです」 | 全会員のタイトル変更が不可、常に発生。回避策:作り直し |
| 依頼 | 直してください | S2 / P2 を提案。9/30 のリリース以降に発生 |
「急ぎです」「困っています」を、影響人数・回避策・発生条件という事実に置き換えるのがポイントです。事実があれば、優先度は開発側が判断できます。
環境情報と証跡の取り方(実際に取得した例)
証跡は「開発者がログを探す時間」をそのまま短縮します。ここでは架空のタスク管理サービスのバグを、Node.js 22.22 で書いた最小のサーバーで再現し、Playwright 1.56.1(Chromium 141)で証跡を集めました。手作業で取る場合の操作も併記します。
環境情報の取り方
| 情報 | 取り方 |
|---|---|
| ブラウザのバージョン | Chrome:メニュー → ヘルプ → Google Chrome について、または chrome://version。Edge:edge://version。Firefox:about:support |
| User-Agent | 開発者ツールのコンソールで navigator.userAgent(今回の環境では HeadlessChrome/141.0.7390.37 を含む1行が返り、OSとバージョンが分かります) |
| 画面幅 | コンソールで window.innerWidth |
| アプリのバージョン | 画面のフッターや設定画面、/version のような確認用ページ、または応答ヘッダー |
| 拡張機能の影響 | シークレットウィンドウ(拡張機能が無効)で再現するか試す |
| 時刻 | 分単位で、タイムゾーンつき(例:15:07 JST) |
ブラウザのコンソールとネットワークタブ
手作業の場合は、F12(Macは Cmd + Option + I)で開発者ツールを開き、Consoleタブの赤いメッセージと、Networkタブで赤くなった行を確認します。
| 操作 | Chrome / Edge |
|---|---|
| 画面遷移してもログを残す | Networkタブの「Preserve log」にチェック |
| キャッシュの影響を除く | 「Disable cache」にチェック |
| 失敗した通信だけ表示 | フィルターの「Has blocked cookies / 4xx / 5xx」やステータス列で並べ替え |
| 通信を開発者へ渡す | 行を右クリック → 「Copy as cURL」(同じリクエストを再送できる) |
| 応答ヘッダーのリクエストID | 行をクリック → Headers → Response Headers の X-Request-Id など |
Playwrightで同じことを自動で行うと、コンソール・ページ内エラー・4xx/5xxの応答をまとめて記録できます。
// collect.js(Playwright 1.56.1 / Chromium 141)
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const context = await browser.newContext({
recordHar: { path: 'trace.har', content: 'embed' }, // 通信の記録(HAR)
viewport: { width: 1000, height: 500 },
});
const page = await context.newPage();
const consoleLines = [];
const networkLines = [];
page.on('console', (m) => consoleLines.push(`[console.${m.type()}] ${m.text()}`));
page.on('pageerror', (e) => consoleLines.push(`[pageerror] ${e.message}`));
page.on('response', (r) => {
if (r.status() >= 400) {
networkLines.push(`${r.request().method()} ${r.url()} -> ${r.status()} ` +
`X-Request-Id: ${r.headers()['x-request-id']}`);
}
});
await page.goto('http://127.0.0.1:7571/');
await page.getByRole('button', { name: '保存' }).click();
await page.waitForTimeout(500);
await page.screenshot({ path: 'screenshot.png', fullPage: true });
console.log('--- console / pageerror ---\n' + consoleLines.join('\n'));
console.log('--- 4xx/5xx responses ---\n' + networkLines.join('\n'));
await context.close(); // ここで HAR が書き出される
await browser.close();
})();
実行結果(node collect.js):
--- console / pageerror ---
[console.error] Failed to load resource: the server responded with a status of 500 (Internal Server Error)
[pageerror] Cannot read properties of undefined (reading 'title')
--- 4xx/5xx responses ---
PUT http://127.0.0.1:7571/api/tasks/42 -> 500 X-Request-Id: 9d64991d-7c69-41c3-bd70-360b3c56710d
「画面側のエラー(TypeError)」と「通信の失敗(500)」の両方が取れているのがポイントです。画面側のエラーだけを報告すると、原因がサーバー側にあることが伝わりません。
HARの保存
HAR(HTTP Archive)は、ネットワークタブの通信を丸ごと保存したJSONです。Chromeでは Networkタブの「Export HAR」ボタン(または右クリック → Save all as HAR)で保存できます。Chrome 130以降、既定の書き出しは Cookie・Set-Cookie・Authorization ヘッダーを除いた「sanitized」版で、機密を含む版が必要なときは Settings → Preferences → Network の「Allow to generate HAR with sensitive data」を有効にして選びます(Chrome DevToolsの公式リファレンスより)。
HARは大きくなりがちなので、失敗した通信だけを jq で抜き出して報告に貼ると読みやすくなります(jq 1.7で実行)。
jq -r '.log.entries[]
| select(.response.status >= 400)
| "\(.startedDateTime) \(.request.method) \(.request.url) -> \(.response.status) req_id=\((.response.headers[] | select(.name|ascii_downcase=="x-request-id")).value) body=\(.response.content.text)"' trace.har
2026-09-30T15:07:31.174Z PUT http://127.0.0.1:7571/api/tasks/42 -> 500 req_id=9d64991d-7c69-41c3-bd70-360b3c56710d body={"error":"internal_error","request_id":"9d64991d-7c69-41c3-bd70-360b3c56710d"}
スクリーンショットと動画
| 環境 | 静止画 | 動画 |
|---|---|---|
| Windows | Win + Shift + S(範囲を選んで撮影) | Snipping Tool の録画、または Win + G |
| Mac | Cmd + Shift + 4(範囲)、Cmd + Shift + 3(全画面) | Cmd + Shift + 5 → 画面収録 |
| Chrome 開発者ツール | Cmd/Ctrl + Shift + P → 「Capture full size screenshot」(ページ全体) | Performance タブや拡張機能 |
撮る前に、時計・URL・エラーメッセージが画面に入っているか確認します。動画は「操作の順番と速さ」が伝わるので、手順が長いバグや断続的なバグに向いています。
サーバーログの抜粋とリクエストID
リクエストIDは、画面で起きたことをサーバーログの1行に結びつける鍵です。応答ヘッダー(X-Request-Id など)や、エラー応答の本文に含まれていることが多いので、報告には必ず書きます。開発者はそのIDで検索するだけで該当行に到達できます。
grep 9d64991d-7c69-41c3-bd70-360b3c56710d server.log | jq -c '{time, level, path, status, msg}'
{"time":"2026-09-30T15:07:31.175Z","level":"error","path":"/api/tasks/42","status":null,"msg":"column \"titel\" of relation \"tasks\" does not exist"}
{"time":"2026-09-30T15:07:31.176Z","level":"info","path":"/api/tasks/42","status":500,"msg":null}
画面を使わずAPIだけで再現できるかも確認しておくと、切り分けが一段進みます(curl -i で応答ヘッダーも取れます)。
curl -s -i -X PUT http://127.0.0.1:7571/api/tasks/42 \
-H 'Content-Type: application/json' -d '{"title":"週次レポート作成"}'
HTTP/1.1 500 Internal Server Error
X-Request-Id: 228cf446-3fd7-40c2-9537-620d70ccca98
Content-Type: application/json
{"error":"internal_error","request_id":"228cf446-3fd7-40c2-9537-620d70ccca98"}
ログを貼るときは、前後3〜5行を含めた「抜粋」にし、個人情報・パスワード・トークン・セッションIDはマスクします(Authorization: Bearer **** のように)。全文が必要なときは、共有範囲を限定したストレージに置いてリンクを貼ります。
再現しないバグ・断続的なバグの書き方
再現しないバグは「再現手順」の代わりに「起きたときの状況」を集めます。1回だけでも、次の項目がそろっていれば調査は始められます。
| 書くこと | 例 |
|---|---|
| 起きた日時(分単位、タイムゾーン) | 2026-09-30 09:12 JST |
| そのとき何をしていたか(直前の操作を3つ) | 一覧を開く → 検索 → 2件目を開く |
| 結果とメッセージ(全文) | 「読み込みに失敗しました」 |
| そのときのリクエストIDやURL | X-Request-Id: …、/tasks?page=3 |
| 同じ操作をやり直した結果 | 直後にやり直すと成功 |
| 発生の傾向 | 朝9時台に多い、件数が多い会員で起きる、Wi-Fi切替の直後 |
| 発生率 | 直近1週間で 30回中 4回 |
断続的なバグは、次のような記録シートを報告に添えると、傾向(時間帯・データ量・ネットワーク)が見えてきます。
| 日時(JST) | 操作 | 結果 | リクエストID | 気づいたこと |
|---|---|---|---|---|
| 09/29 09:12 | 一覧 → 検索 | 失敗 | 4c1e… | 朝の混雑時間帯 |
| 09/29 13:40 | 一覧 → 検索 | 成功 | 88a0… | |
| 09/30 09:05 | 一覧 → 検索 | 失敗 | 0d77… | 検索語に全角スペース |
「再現しない」は「情報が足りない」とは違います。時刻とリクエストIDがあれば、開発者はサーバー側のログや負荷の記録から原因を追えます。
AI(Claude Code など)に修正を依頼するときの書き方
AIコーディングツールに直してもらうときも、必要な情報はバグ報告と同じです。違いは、「変更してよい範囲」と「完了の条件」を明示すること、そしてエラーは要約せず全文を渡すことです。
## 依頼:タスクのタイトル更新が失敗するバグを直してください
### 状況
- リポジトリ:task-app(ブランチ main、コミット 3f1c9e2)
- 対象:PUT /api/tasks/:id の処理(src/routes/tasks.js)と編集画面(public/edit.html)
- 再現コマンド:`npm test -- tasks.test.js`(テスト "updates title" が失敗)
### 期待と実際
- 期待:タイトルを更新すると 200 と更新後のタスクが返り、画面に「保存しました」と出る
- 実際:500 が返り、画面側は TypeError で止まる
### 証跡(全文)
- サーバーログ:column "titel" of relation "tasks" does not exist
- ブラウザ:[pageerror] Cannot read properties of undefined (reading 'title')
### 制約
- DBスキーマとAPIの応答形式は変えない
- 変更は上の2ファイルと、そのテストに限定する
- 既存のテストはすべて通す
### 完了条件
- `npm test` がすべて成功する
- 失敗応答(4xx/5xx)のとき画面が「保存に失敗しました」と表示する
- 変更点と理由を3行で説明する
### 進め方
- まず原因の仮説と修正方針を説明し、私が承認してから変更してください
| 書くと効く項目 | 理由 |
|---|---|
| 再現コマンドと失敗するテスト名 | AIが「直った」を自分で確認できる |
| エラーの全文とスタックトレース | 要約すると原因の行番号が失われる |
| 変更してよい範囲 | 関係ないファイルの整形や設計変更を防ぐ |
| 完了条件 | 「動いた」の定義がそろい、やり直しが減る |
| 承認してから変更 | 大きな変更の前に方針を確認できる |
報告後の流れと、報告者が確認すること
報告は出して終わりではなく、「検証」まで含めてひとつの流れです。報告者が最後に再現手順で確認することで、「直したつもり」を防げます。
| 段階 | 主な担当 | やること | 報告者が確認すること |
|---|---|---|---|
| 1. トリアージ | リーダー・QA | 重複確認、重大度・優先度の確定、担当決定 | 優先度が下がった理由に納得できるか。追加情報を求められていないか |
| 2. 担当・調査 | 開発者 | 再現、原因特定、修正方針 | 「再現しない」と言われたら、環境やデータの違いを補足する |
| 3. 修正 | 開発者 | 修正とテストの追加、プルリクエスト | 修正版がどの環境・バージョンに入るか |
| 4. 検証 | 報告者・QA | 報告した再現手順で確認、周辺機能も確認 | 期待した結果になったか。似た操作でも起きないか |
| 5. クローズ | リーダー | 完了理由を記録して閉じる | 完了理由(対応済み / 仕様どおり / 重複 / 再現しない / 対応しない)が正しいか |
「仕様どおり」で閉じられたときは、期待した結果の根拠(仕様書の該当箇所、他画面との整合)を添えて再確認を依頼します。それでも仕様なら、改善要望として別チケットにするのが整理しやすい進め方です。
よくある質問
Q. バグか仕様か判断できないときは、どう書けばよいですか? A. 「期待した結果」に根拠(仕様書の項目、以前の動き、他の画面との整合)を添えて、判断は開発側に委ねる書き方にします。「仕様の可能性もありますが、期待は〜です(根拠:〜)」で十分です。
Q. 1つの操作で複数のバグを見つけました。1件にまとめてよいですか? A. 1件1バグが原則です。担当・修正・検証の単位がそろい、片方だけ直ったときに閉じられる状態になります。関連がある場合は、それぞれの本文に相互のリンクを書きます。
Q. 再現手順が20ステップになります。どうすればよいですか? A. 「前提(ログイン済み、タスク #42 が存在)」を先にまとめ、手順は結果に影響するものだけに絞ります。途中の状態はスクリーンショットや対象データのIDで代用できます。
Q. ログに個人情報やトークンが含まれています。
A. 報告に貼る前にマスクし(Bearer ****、メールアドレスは s***@example.com)、全文が必要な場合は共有範囲を限定した場所に置いてリンクを貼ります。HARはChromeの既定(sanitized)で書き出します。
まとめ
- 良いバグ報告の条件は、再現手順・期待と実際・環境・証跡・影響範囲・頻度の6つ
- テンプレートはMarkdown・GitHub Issue Forms・Jira・Backlogのどれでも中身は同じ。書けない項目は「不明」と残す
- 重大度(S1〜S4)は事実、優先度(P1〜P4)は判断。組み合わせ表で初期値を提案し、トリアージで確定する
- 証跡はコンソール・失敗した通信・リクエストID・ログの抜粋。リクエストIDがあれば開発者は1行で該当箇所に届く
- 再現しないバグは「状況」を集める。日時・直前の操作・リクエストID・発生率を記録シートに
- AIに頼むときはエラー全文・変更範囲・完了条件を明示する
- 報告後は検証まで報告者の仕事。完了理由を確認して閉じる
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「バグ報告の書き方|コピペ用テンプレートと重大度判定表」
株式会社RJCでは、バグ報告のように「相手が動きやすい情報の渡し方」を、プロジェクトの中で仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。