はじめに

バグ修正は開発者の時間を大きく消費する作業です。エラーメッセージの解読、原因箇所の特定、適切な修正方法の検討と、多くのステップが必要になります。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にエラーを共有し、原因と修正方法を分析
  • スタックトレース解析: 問題箇所の迅速な特定と根本原因の分析
  • 修正提案の適用: 複数の修正案から最適なものを選択して適用
  • ガードレール機能: ターミナルエラーのリアルタイム検出と自動修正
  • デバッグワークフロー: 体系的なアプローチによる効率的な問題解決

これらのテクニックを活用することで、バグ修正にかかる時間を大幅に短縮し、より堅牢なソフトウェアを開発できます。

参考リンク