Skip to content

Lab 3.1: Investigate a Bug in Plan Mode

Goal: Use the plan agent to explore a real bug without making any changes, write a fix plan, then switch to build and execute.

Time: 30–45 minutes.

What you'll learn: - How to stay in plan mode and gather context. - How to ask the agent for a structured plan. - The difference between jumping to build vs. exploring first.


The Setup

You'll work with a sample Node.js to-do app that has a crash. The app is provided at labs/sample-repo-buggy-todo-app/. Clone it and follow along.

cd ~/Documents/opencode-course/labs/sample-repo-buggy-todo-app
cat README.md  # Read the setup instructions

The app is a simple Express server with a bug in the /api/tasks endpoint. When you try to fetch tasks for a user that doesn't exist, it crashes with:

TypeError: Cannot read property 'length' of undefined
  at getTasks (lib/db.js:32)

Part 1: Explore in Plan Mode (No Edits)

Step 1: Start OpenCode in the repo.

opencode

You'll see the TUI. At the top, it says [Build] by default.

Step 2: Switch to plan mode by pressing Tab.

[TUI updates]
Mode indicator changes to [Plan]

If the TUI doesn't show a mode indicator, type a message first and look at the status line.

Step 3: Ask the plan agent to investigate the crash.

>> What causes the crash when fetching tasks for a user that doesn't exist?

The plan agent will: - Read the error message you provide. - Look at the lib/db.js file (where the error occurs). - Trace back to the route that calls getTasks(). - Find where the user lookup happens.

Step 4: Ask follow-up questions in plan mode to dig deeper.

>> Where is the user validation happening in the middleware?

>> What does the `fetchUser()` function return when a user is not found?

>> Which routes are vulnerable to this same crash?

Critical: Do not flip to build mode yet. You're gathering intelligence.


Part 2: Write a Fix Plan (Still Plan Mode)

Step 5: Ask the plan agent to summarize its findings.

>> Based on your investigation, write a 5-bullet plan to fix this crash.
>> Format: each bullet is one concrete action.
>> Use file names, not vague descriptions.

You should get something like:

1. In lib/db.js, add a guard at line 30: if (!user) return [];
2. Add a unit test in tests/db.test.js for getTasks(null)
3. In routes/tasks.js, verify the middleware always sets request.user
4. Check if any other functions assume request.user exists
5. Run npm test to confirm no regressions

Step 6: Review the plan carefully.

Ask yourself: - Do the steps make sense in order? - Are they specific (file names, line numbers)? - Could you hand this plan to another engineer and they'd understand it?

If the plan is vague, ask the agent to refine it. Stay in plan mode as long as you're refining.

>> Bullet 3 is vague. How do we verify the middleware always sets request.user?
>> What file should I look at?

Keep refining until you have a plan you could explain to your team.


Part 3: Execute the Plan (Build Mode)

Step 7: Once you approve the plan, press Tab to switch to build mode.

[TUI updates]
Mode indicator changes to [Build]

Step 8: Ask the build agent to apply the plan.

>> Apply the plan we just wrote.
>> Do not deviate from it.

The build agent will: - Edit the files listed in the plan. - Run tests. - Ask for approval before committing.

Step 9: When it asks for approval (e.g., "Edit lib/db.js?"), review carefully.

  • Does the change match the plan?
  • Is it the only change it's proposing?
  • Does it make sense in context?

Approve each change. If the agent deviates, deny and ask why.

Step 10: Run the full test suite.

>> Run npm test to verify the fix works and nothing broke.

Step 11: Commit.

>> Commit with a message explaining the fix.

Part 4: Verification

Step 12: Confirm the fix works.

Exit OpenCode (Ctrl+C or type /exit). Then:

npm test

All tests should pass. Specifically, the test for getTasks(null) should pass.

Step 13: Verify the repo is clean.

git status

You should see: - Modified files (the ones you fixed). - One new commit in the log. - No untracked files.


Reflection

After you finish, answer these in your own words:

  1. How much time did you spend in plan mode vs. build mode? Why?
  2. Did the agent suggest anything you had to reject? Why was it wrong?
  3. If you had jumped straight to build mode at the start, what might have gone wrong?
  4. What was the hardest part of writing the plan?

Write 3–4 sentences. Save it in a text file for reference.


Troubleshooting

Q: The agent doesn't find the bug. A: Ask it directly where the crash happens. Paste the error message. Then ask it to trace backward: "Where is getTasks() called?"

Q: I flip to build mode and the agent tries to edit files that weren't in the plan. A: Deny the approval. Ask the agent: "Why are you editing this file? It's not in the plan."

Q: Tests still fail after the fix. A: You may have missed a case. Flip back to plan mode and ask: "What did we miss? Where else might user be undefined?"

Q: The agent asks for approval dozens of times. A: That's normal for a multi-file change. Review each approval carefully. You can also ask the agent to batch changes into one big edit instead.


Next Steps

Great job! You've practiced the "explore → plan → execute" workflow. This is the habit you're building.

Next: Lab 3.2 — Stay in Plan Mode (even after you understand the problem).