はじめに#
バグ修正は開発者の時間を大きく消費する作業です。エラーメッセージの解読、原因箇所の特定、適切な修正方法の検討と、多くのステップが必要になります。Cursorを活用すれば、AIがエラーを分析し、原因を特定し、修正案まで提示してくれます。
本記事では、Cursorを使った効率的なバグ修正手法を解説します。この記事を読むことで、以下のことができるようになります。
- エラーメッセージをAgentに共有し、原因を分析してもらえる
- スタックトレースから問題箇所を迅速に特定できる
- AIによる修正提案を評価し、適用できる
- ガードレール機能でターミナルエラーを自動修正できる
- 効率的なデバッグワークフローを確立できる
実行環境と前提条件#
実行環境#
| 項目 |
要件 |
| オペレーティングシステム |
Windows 10以上、macOS 10.15以上、Ubuntu 20.04以上 |
| Cursor バージョン |
2.3以降(2026年1月時点の安定版) |
| インターネット接続 |
必須(AIモデル利用に必要) |
| 料金プラン |
Hobby(無料)以上 |
前提条件#
- Cursorがインストールされ、アカウントでログイン済みであること
- デバッグ対象のプロジェクトが開かれていること
- 基本的なデバッグの概念(ブレークポイント、スタックトレース等)を理解していること
- ターミナル操作の基本知識があること
期待される結果#
本記事の手順を完了すると、以下の状態になります。
- エラーメッセージから迅速に原因を特定できる
- AIの修正提案を活用して効率的にバグを解消できる
- ガードレール機能で単純なエラーを自動修正できる
- デバッグ時間を大幅に短縮できる
エラーメッセージの共有と分析#
バグ修正の第一歩は、エラーメッセージをAgentに共有して分析を依頼することです。
基本的なエラー共有#
Agent(Ctrl+I)を開き、エラーメッセージを貼り付けて分析を依頼します。
1
2
3
4
5
6
|
指示例:
以下のエラーが発生しています。原因と修正方法を教えてください。
TypeError: Cannot read properties of undefined (reading 'map')
at UserList (src/components/UserList.tsx:15:23)
at renderWithHooks (node_modules/react-dom/cjs/react-dom.development.js:14985:18)
|
Agentによる分析結果#
Agentは以下のような分析を提供します。
1
2
3
4
5
6
7
8
9
10
11
|
Agentの分析結果例:
## エラー分析
### 原因
`UserList`コンポーネントの15行目で、`undefined`の値に対して
`.map()`メソッドを呼び出しています。これは、データがまだ
ロードされていない状態でレンダリングが行われた際に発生します。
### 該当コード
@src/components/UserList.tsx の15行目を確認すると:
|
1
2
3
4
5
6
7
8
9
10
|
// 問題のあるコード
const UserList = ({ users }) => {
return (
<ul>
{users.map(user => ( // users が undefined の場合にエラー
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};
|
1
2
3
4
5
6
|
### 修正提案
以下のいずれかの方法で修正できます:
1. オプショナルチェーン(推奨)
2. デフォルト値の設定
3. 条件付きレンダリング
|
コンテキストを含めたエラー共有#
関連ファイルを@メンションして、より正確な分析を得られます。
1
2
3
4
5
6
|
指示例:
以下のエラーが発生しています。
@src/components/UserList.tsx と @src/hooks/useUsers.ts を確認して、
原因と修正方法を提案してください。
TypeError: Cannot read properties of undefined (reading 'map')
|
スタックトレースからの原因特定#
複雑なエラーでは、スタックトレースから問題箇所を特定する必要があります。
スタックトレースの解析#
1
2
3
4
5
6
7
8
9
10
|
指示例:
以下のスタックトレースを解析して、
根本原因と問題が発生している箇所を特定してください。
Error: ENOENT: no such file or directory, open '/app/config/production.json'
at Object.openSync (node:fs:603:3)
at Object.readFileSync (node:fs:471:35)
at loadConfig (src/config/loader.ts:23:18)
at initializeApp (src/app.ts:45:12)
at Object.<anonymous> (src/index.ts:8:1)
|
原因特定のフロー#
flowchart TD
A[スタックトレースを確認] --> B[最下層のフレームを特定]
B --> C[自分のコードの<br/>最初のフレームを確認]
C --> D[該当ファイルを開く]
D --> E[問題箇所をAgentに共有]
E --> F[根本原因を分析]
F --> G[修正案を生成]複数のエラーが連鎖している場合#
1
2
3
4
5
6
7
8
|
指示例:
以下のエラーログには複数のエラーが含まれています。
根本原因となっている最初のエラーを特定し、
その修正によって解消される連鎖エラーも説明してください。
[Error] Database connection failed
[Error] UserService initialization failed
[Error] Application startup failed
|
修正提案の適用#
Agentが提案する修正を確認し、適用します。
修正提案の例#
エラー分析後、Agentは具体的な修正コードを提案します。
1
2
3
|
Agentの修正提案:
3つの修正方法を提案します。
|
方法1: オプショナルチェーンとNullish coalescing#
1
2
3
4
5
6
7
8
9
|
const UserList = ({ users }) => {
return (
<ul>
{(users ?? []).map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};
|
方法2: 早期リターン#
1
2
3
4
5
6
7
8
9
10
11
12
13
|
const UserList = ({ users }) => {
if (!users || users.length === 0) {
return <p>ユーザーがいません</p>;
}
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};
|
方法3: ローディング状態の考慮#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
const UserList = ({ users, isLoading }) => {
if (isLoading) {
return <p>読み込み中...</p>;
}
if (!users || users.length === 0) {
return <p>ユーザーがいません</p>;
}
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};
|
修正の適用と確認#
提案された修正を適用する際は、差分プレビューで変更内容を確認します。
1
2
3
|
指示例:
方法3のローディング状態を考慮した修正を適用してください。
useUsersフックにisLoading状態も追加してください。
|
修正後の動作確認#
1
2
3
4
|
指示例:
修正を適用しました。
ターミナルで開発サーバーを再起動し、
エラーが解消されたか確認してください。
|
ガードレール機能によるエラー自動修正#
Cursor 2.2以降では、ターミナルで発生したエラーを自動的に検出・修正するガードレール機能が利用できます。
ガードレールの仕組み#
ガードレールは、ターミナルで発生したエラーをリアルタイムで監視し、自動修正を提案します。
flowchart LR
A[コマンド実行] --> B{エラー発生?}
B -->|いいえ| C[完了]
B -->|はい| D[エラーを検出]
D --> E[原因を分析]
E --> F[修正を提案]
F --> G{自動適用?}
G -->|はい| H[修正を適用]
G -->|いいえ| I[ユーザーに確認]
H --> J[再実行]
I --> J
J --> B
~~~
### コンパイルエラーの自動修正
TypeScriptのコンパイルエラーが発生した場合、ガードレールが自動で修正を提案します。
~~~bash
# ターミナルで発生したエラー
$ npm run build
src/services/user.service.ts:45:12 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
45 this.setAge(user.age);
~~~~~~~~
~~~
ガードレールは即座にこのエラーを検出し、修正を提案します。
~~~text
ガードレールの提案:
型の不一致を検出しました。
user.age が string 型ですが、setAge は number を期待しています。
修正案:
this.setAge(parseInt(user.age, 10));
または、user.age の型定義を修正:
age: number; // string → number
適用しますか? [適用] [スキップ]
~~~
### リンターエラーの自動修正
ESLintエラーも同様に自動修正できます。
~~~bash
$ npm run lint
src/components/Button.tsx
12:5 error 'onClick' is missing in props validation react/prop-types
15:9 error Unexpected console statement no-console
~~~
~~~text
ガードレールの提案:
2件のESLintエラーを検出しました。
1. prop-types エラー
→ TypeScript の型定義を追加することで解決
2. no-console エラー
→ console.log を削除または logger に置き換え
両方の修正を適用しますか?
~~~
### テスト失敗の自動修正
テスト実行時のエラーも分析します。
~~~bash
$ npm test
FAIL src/utils/math.test.ts
● add › should add two numbers correctly
expect(received).toBe(expected)
Expected: 5
Received: "23"
~~~
~~~text
ガードレールの提案:
テストが失敗しています。
文字列の結合が行われており、数値の加算が行われていません。
原因:引数が文字列として渡されている可能性があります。
修正案:
1. 関数内で Number() による型変換を追加
2. TypeScript の型定義を厳密化
修正を適用しますか?
~~~
## デバッグワークフローの効率化
Cursorを活用した効率的なデバッグワークフローを紹介します。
### 体系的なデバッグアプローチ
```mermaid
flowchart TD
A[バグ報告を受ける] --> B[再現手順を確認]
B --> C[エラーログを収集]
C --> D[Agentにエラーを共有]
D --> E[原因分析を依頼]
E --> F{原因特定?}
F -->|いいえ| G[追加情報を収集]
G --> D
F -->|はい| H[修正案を検討]
H --> I[修正を適用]
I --> J[テストで検証]
J --> K{修正成功?}
K -->|いいえ| L[別のアプローチを検討]
L --> H
K -->|はい| M[リグレッションテスト追加]
M --> N[完了]バグ報告からの分析#
バグ報告の内容をAgentに共有して分析を依頼します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
指示例:
以下のバグ報告を分析し、原因を特定してください。
【バグ報告】
タイトル: ユーザー検索で日本語が正しく検索できない
再現手順:
1. 検索ボックスに「田中」と入力
2. 検索ボタンをクリック
3. 結果が0件と表示される
期待される動作: 「田中」を含むユーザーが表示される
実際の動作: 結果が0件
環境: Chrome 120, Windows 11
|
デバッグモードの活用#
Cursor 2.2で追加されたデバッグモードを使うと、Agentがブレークポイントを設定して変数の状態を調査します。
1
2
3
4
|
指示例:
デバッグモードで @src/services/search.service.ts の
search メソッドを調査してください。
「田中」で検索した際の変数の状態を確認したいです。
|
ログ追加による調査#
1
2
3
4
5
6
7
|
指示例:
原因特定のために、以下の関数にデバッグログを追加してください。
- 入力値
- 各処理ステップの結果
- 最終的な戻り値
@src/services/search.service.ts の search メソッド
|
ログが追加されたコード#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
async search(query: string): Promise<User[]> {
console.log('[search] Input query:', query);
console.log('[search] Query length:', query.length);
console.log('[search] Query encoded:', encodeURIComponent(query));
const normalizedQuery = this.normalizeQuery(query);
console.log('[search] Normalized query:', normalizedQuery);
const results = await this.userRepository.search(normalizedQuery);
console.log('[search] Results count:', results.length);
console.log('[search] Results:', JSON.stringify(results, null, 2));
return results;
}
|
ログ出力からの原因特定#
1
2
3
4
5
6
7
8
9
|
指示例:
ログを追加して実行したところ、以下の出力が得られました。
この結果から原因を特定し、修正してください。
[search] Input query: 田中
[search] Query length: 2
[search] Query encoded: %E7%94%B0%E4%B8%AD
[search] Normalized query:
[search] Results count: 0
|
1
2
3
4
5
6
7
8
9
10
11
|
Agentの分析結果:
## 原因特定
normalizeQuery の結果が空文字列になっています。
これが原因で検索結果が0件になっています。
normalizeQuery メソッドを確認したところ、
ASCII文字以外を除去する処理が含まれていました。
### 問題のあるコード
|
1
2
3
|
normalizeQuery(query: string): string {
return query.replace(/[^\x00-\x7F]/g, ''); // ASCII以外を除去
}
|
1
2
3
|
### 修正案
日本語を含むUnicode文字を保持するように修正:
|
1
2
3
4
5
6
|
normalizeQuery(query: string): string {
return query
.trim()
.toLowerCase()
.replace(/\s+/g, ' '); // 空白の正規化のみ
}
|
複雑なバグの調査テクニック#
再現が難しいバグの調査#
間欠的に発生するバグや、特定条件でのみ発生するバグの調査方法です。
1
2
3
4
5
6
|
指示例:
以下のバグは10回に1回程度しか発生しません。
考えられる原因と調査方法を提案してください。
症状: 注文処理が稀に失敗する
エラー: "Deadlock detected"
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
Agentの分析:
## デッドロックの原因候補
1. **並行トランザクションの競合**
- 複数の注文が同時に処理される際にロック競合
2. **トランザクションの順序不整合**
- 異なる処理が異なる順序でテーブルをロック
3. **長時間トランザクション**
- タイムアウト前にロック解放が行われない
## 調査方法
1. ログにトランザクションIDと実行時間を追加
2. データベースのデッドロックログを確認
3. 負荷テストで再現を試みる
|
メモリリークの調査#
1
2
3
4
5
|
指示例:
アプリケーションを長時間稼働させるとメモリ使用量が
増加し続けます。メモリリークの原因を調査してください。
@src/services/event.service.ts
|
非同期処理のバグ#
1
2
3
4
5
|
指示例:
以下のコードで「Promise resolution is still pending」という
警告が出ています。原因と修正方法を教えてください。
@src/controllers/upload.controller.ts
|
よくあるトラブルと対処法#
Agentの分析が的外れな場合#
より多くのコンテキストを提供します。
1
2
3
4
5
6
7
8
9
10
11
|
追加情報を含めた指示例:
先ほどの分析は的外れでした。以下の追加情報を考慮してください:
- このプロジェクトはNest.js を使用しています
- データベースはPostgreSQLです
- 認証にはJWTを使用しています
@src/auth/auth.module.ts
@src/config/database.config.ts
この情報を踏まえて再分析してください。
|
修正が別のバグを引き起こした場合#
1
2
3
4
5
6
7
8
|
指示例:
前回の修正を適用したところ、別のエラーが発生しました。
新しいエラー:
"Cannot find module './utils' from 'src/services/user.service.ts'"
元の修正と今回のエラーの関係を分析し、
両方を解決する修正を提案してください。
|
本番環境でのみ発生するバグ#
1
2
3
4
5
6
7
8
9
|
指示例:
このバグはローカル環境では再現できず、
本番環境でのみ発生します。
環境の違い:
- ローカル: Node.js 20, SQLite
- 本番: Node.js 18, PostgreSQL
環境差異が原因となる可能性を分析してください。
|
まとめ#
Cursorを活用したバグ修正は、エラーの原因特定から修正までのプロセスを大幅に効率化するAI駆動開発の重要な手法です。本記事で解説した内容をまとめます。
- エラーメッセージの共有: Agentにエラーを共有し、原因と修正方法を分析
- スタックトレース解析: 問題箇所の迅速な特定と根本原因の分析
- 修正提案の適用: 複数の修正案から最適なものを選択して適用
- ガードレール機能: ターミナルエラーのリアルタイム検出と自動修正
- デバッグワークフロー: 体系的なアプローチによる効率的な問題解決
これらのテクニックを活用することで、バグ修正にかかる時間を大幅に短縮し、より堅牢なソフトウェアを開発できます。
参考リンク#