7 min reading · Practice at your pace
Debug Code with AI: Reproduce, Fix and Test
Give AI a reproducible error, inspect the smallest fix and run the relevant tests. Follow a real JavaScript debugging task, then try the same failure and validation revision.
Debug code with a failure you can reproduce
Give AI the relevant code, exact failure and expected behavior. Ask for an explanation and a small correction, then run meaningful checks. Code that looks plausible or passes a few tests can still have untested defects.
A JavaScript bug, a small fix and a tested revision
In this cloud Work example, a basket function skipped its final item. Work returned the source, tests and run notes. The initial fix passed the four unchanged tests; a validation follow-up added five cases. The returned code was also tested independently.
Three versions, three checked outcomes
| Item | Details |
|---|---|
| Broken sample | Four tests: one passed, three failed. The two-line basket returned 2,400 cents instead of 2,800. |
| Smallest correction | The loop includes the final item. The same four tests passed; the supplied test file stayed unchanged. |
| Focused revision | Reject negative or fractional quantity/unitCents with RangeError. The original four tests plus five new cases passed. |
✔ empty basket
✔ single line
✔ two lines
✔ zero quantity
✔ negative quantity rejected
✔ fractional quantity rejected
✔ negative unitCents rejected
✔ fractional unitCents rejected
✔ zero unitCents line
tests 9 | pass 9 | fail 0Choose Chat help or Work execution
Use Chat to discuss a snippet, explain an error or request a review. Use Work when the task needs supported workspace actions such as creating files and running a test command. An answer containing a command is not evidence that it ran.
For a Python failure, include the full traceback, Python and package versions, a minimal input and the result you expected. Ask for the smallest correction and a regression case. Run that case in the same environment before accepting the fix.
Choose the kind of code help
| Item | Details |
|---|---|
| Explain code | Supply a short snippet and your experience level. Check the explanation against the code; ask why a step exists. |
| Debug a failure | Supply a minimal reproduction, exact error or wrong result, environment and expected result. Preserve the failure before changing code. |
| Review a change | Supply the relevant diff and requirements. Ask for specific defects, reproducing inputs and useful tests; inspect each finding. |
| Run and revise a small project | In Work, define the allowed files, commands and acceptance checks. Review the delivered files and actual results. Local project access requires its supported client and permissions. |
1. Reproduce the wrong total
The function should total every line item in integer cents. Three items at 800 cents and two at 200 cents should total 2,800. The broken loop skips the final item and returns 2,400. The first version uses nonnegative integer inputs.
function totalCents(items) {
let total = 0;
for (let i = 0; i < items.length - 1; i++) {
total += items[i].quantity * items[i].unitCents;
}
return total;
}
module.exports = { totalCents };
const test = require('node:test');
const assert = require('node:assert/strict');
const { totalCents } = require('./total.js');
test('empty basket', () => assert.equal(totalCents([]), 0));
test('single line', () => assert.equal(totalCents([{quantity: 3, unitCents: 800}]), 2400));
test('two lines', () => assert.equal(totalCents([{quantity: 3, unitCents: 800}, {quantity: 2, unitCents: 200}]), 2800));
test('zero quantity', () => assert.equal(totalCents([{quantity: 0, unitCents: 900}, {quantity: 2, unitCents: 100}]), 200));
node --test total.test.js✔ empty basket
✖ single line 0 !== 2400
✖ two lines 2400 !== 2800
✖ zero quantity 0 !== 200
tests 4 | pass 1 | fail 32. Inspect the smallest correction
The first fix changes only the loop bound from i < items.length - 1 to i < items.length. Inspect the change instead of replacing the whole function without understanding it. All four original tests then pass without changing them.
function totalCents(items) {
let total = 0;
for (let i = 0; i < items.length; i++) {
total += items[i].quantity * items[i].unitCents;
}
return total;
}
module.exports = { totalCents };
✔ empty basket
✔ single line
✔ two lines
✔ zero quantity
tests 4 | pass 4 | fail 03. Add one requirement and preserve the working cases
The follow-up adds a defined validation requirement: quantity and unitCents must each be nonnegative integers. It preserves the original four tests and adds five cases. Zero remains valid. This is a new requirement, separate from correcting the original loop.
Revise only this basket project. Reject a negative or non-integer quantity or unitCents with a RangeError. A quantity of zero is valid. Keep totalCents and the CommonJS export, preserve the original four tests byte-for-byte, and add tests for negative quantity, fractional quantity, negative unitCents, fractional unitCents, and a zero unitCents line. Run the full nine-test suite and record the actual result in DEBUGGING.md. Deliver the complete revised source, test file and notes. No external dependencies, browsing, connected accounts, publishing or deployment. Do not describe this bounded validation as comprehensive security or all possible input validation.function totalCents(items) {
let total = 0;
for (let i = 0; i < items.length; i++) {
const quantity = items[i].quantity;
const unitCents = items[i].unitCents;
if (!Number.isInteger(quantity) || quantity < 0) {
throw new RangeError('quantity must be a nonnegative integer');
}
if (!Number.isInteger(unitCents) || unitCents < 0) {
throw new RangeError('unitCents must be a nonnegative integer');
}
total += quantity * unitCents;
}
return total;
}
module.exports = { totalCents };
Inspect the complete revised test file
The original four tests remain at the beginning; five new cases follow.
const test = require('node:test');
const assert = require('node:assert/strict');
const { totalCents } = require('./total.js');
test('empty basket', () => assert.equal(totalCents([]), 0));
test('single line', () => assert.equal(totalCents([{quantity: 3, unitCents: 800}]), 2400));
test('two lines', () => assert.equal(totalCents([{quantity: 3, unitCents: 800}, {quantity: 2, unitCents: 200}]), 2800));
test('zero quantity', () => assert.equal(totalCents([{quantity: 0, unitCents: 900}, {quantity: 2, unitCents: 100}]), 200));
test('negative quantity rejected', () => assert.throws(() => totalCents([{quantity: -1, unitCents: 100}]), RangeError));
test('fractional quantity rejected', () => assert.throws(() => totalCents([{quantity: 1.5, unitCents: 100}]), RangeError));
test('negative unitCents rejected', () => assert.throws(() => totalCents([{quantity: 1, unitCents: -50}]), RangeError));
test('fractional unitCents rejected', () => assert.throws(() => totalCents([{quantity: 1, unitCents: 2.5}]), RangeError));
test('zero unitCents line', () => assert.equal(totalCents([{quantity: 2, unitCents: 0}, {quantity: 3, unitCents: 100}]), 300));
4. Check what changed and what the tests cover
The nine cases check the basket arithmetic and the new validation rules. They do not cover every input shape, large-number overflow, framework integration or comprehensive security. Run the checks your own project needs before using a change.
Read the Work request and replies
The original conversation is preserved here.
Create a tiny JavaScript debugging project for a workshop supply basket, in your cloud workspace. Use Node.js and CommonJS with no external dependencies. Use only the sample below: no browsing, connected accounts, local computer folders, installation, deployment or publishing.
The contract: totalCents takes an array of line items with quantity and unitCents, and returns their total in integer cents. For this first version, inputs are nonnegative integer values. Preserve the exported function name and CommonJS interface.
First create the broken total.js and the four tests exactly as supplied. Run node --test total.test.js BEFORE fixing anything; retain the complete baseline test output, including failed cases. Then make the smallest fix and rerun the same tests. Deliver total.js, total.test.js and a short DEBUGGING.md explaining the root cause, exact before/after results and actual Node version/commands. Say explicitly if a command could not run. Do not add features or silently rewrite the baseline tests. I will request a focused revision afterward.
total.js:
function totalCents(items) {
let total = 0;
for (let i = 0; i < items.length - 1; i++) {
total += items[i].quantity * items[i].unitCents;
}
return total;
}
module.exports = { totalCents };
total.test.js:
const test = require('node:test');
const assert = require('node:assert/strict');
const { totalCents } = require('./total.js');
test('empty basket', () => assert.equal(totalCents([]), 0));
test('single line', () => assert.equal(totalCents([{quantity: 3, unitCents: 800}]), 2400));
test('two lines', () => assert.equal(totalCents([{quantity: 3, unitCents: 800}, {quantity: 2, unitCents: 200}]), 2800));
test('zero quantity', () => assert.equal(totalCents([{quantity: 0, unitCents: 900}, {quantity: 2, unitCents: 100}]), 200));
Done. The tiny debugging project is created in the cloud workspace at workshop-supply-basket/, and all three requested files are delivered.
What happened
Baseline (broken total.js, exact command node --test total.test.js → exit code 1):
✔ empty basket
✖ single line 0 !== 2400
✖ two lines 2400 !== 2800
✖ zero quantity 0 !== 200
tests 4 | pass 1 | fail 3
Root cause: the loop bound i < items.length - 1 stops one item early, so the last line item is never added. That's why the only error-free case is the empty basket (0 by coincidence).
Smallest fix (one token changed, nothing else touched):
- for (let i = 0; i < items.length - 1; i++) {
+ for (let i = 0; i < items.length; i++) {
After (same command → exit code 0):
✔ empty basket
✔ single line
✔ two lines
✔ zero quantity
tests 4 | pass 4 | fail 0
The four supplied tests were not modified; the baseline run predates the fix. No command failed to run — Node v24.21.0 ran node --test total.test.js successfully both before and after.
Delivered files
- total.js — fixed, CommonJS, module.exports = { totalCents } preserved
- total.test.js — the four tests exactly as supplied
- DEBUGGING.md — root cause, environment, commands, and full before/after output
Ready for your focused revision whenever you are.Revision complete. The basket project now enforces the requested input rules, and all nine tests pass.
What changed
total.js — added a guard inside the loop. quantity and unitCents must each be a nonnegative integer; otherwise a RangeError is thrown. Zero is accepted for both. Number.isInteger() also rejects NaN/Infinity/fractions in one check. totalCents and module.exports = { totalCents } are unchanged.
function totalCents(items) {
let total = 0;
for (let i = 0; i < items.length; i++) {
const quantity = items[i].quantity;
const unitCents = items[i].unitCents;
if (!Number.isInteger(quantity) || quantity < 0) {
throw new RangeError('quantity must be a nonnegative integer');
}
if (!Number.isInteger(unitCents) || unitCents < 0) {
throw new RangeError('unitCents must be a nonnegative integer');
}
total += quantity * unitCents;
}
return total;
}
module.exports = { totalCents };
total.test.js — the original four tests are preserved byte-for-byte; five appended tests cover negative quantity, fractional quantity, negative unitCents, fractional unitCents, and a zero-unitCents line.
Actual result — node --test total.test.js (Node v24.21.0), exit code 0
✔ empty basket
✔ single line
✔ two lines
✔ zero quantity
✔ negative quantity rejected
✔ fractional quantity rejected
✔ negative unitCents rejected
✔ fractional unitCents rejected
✔ zero unitCents line
tests 9 | pass 9 | fail 0
9 pass / 0 fail. No command failed to run.
Delivered files (updated)
- total.js — revised source
- total.test.js — nine-test suite
- DEBUGGING.md — Revision 1 section with the recorded nine-test output
DEBUGGING.md explicitly labels this as bounded validation for the specified quantity/unitCents rules only — not comprehensive security or all possible input validation. No external dependencies, browsing, connected accounts, publishing, or deployment were used.Review the actual change against its contract
Use this practice request to review the diff from the original and corrected files. Check the behavior and tests rather than judging a plausible explanation. The review request is separate from the debugging task.
Review this actual before/after diff against the stated contract. This is a review request, not permission to change files.
Contract: totalCents totals every line item in integer cents. The supplied first-version inputs have nonnegative integer quantity and unitCents values. Preserve totalCents and its CommonJS export.
For each finding, give the affected line, a concrete input, the expected result, the observed or proposed check and why it matters. Separate a defect under this contract from a proposed new requirement. Say which checks actually ran and which you only suggest.
Check the empty, single-line, two-line and zero-quantity cases. Explain whether the original tests remain useful. Do not claim a complete repository or security review.
--- original/total.js
+++ corrected/total.js
@@ -1,8 +1,8 @@
function totalCents(items) {
let total = 0;
- for (let i = 0; i < items.length - 1; i++) {
+ for (let i = 0; i < items.length; i++) {
total += items[i].quantity * items[i].unitCents;
}
return total;
}
module.exports = { totalCents };- Does the change fix the wrong result for the same supplied input?
- Are the function name, export and previously working cases preserved?
- Can each claimed defect be reproduced with a specific input and expected result?
- Are additional validation rules identified as new requirements rather than existing-contract failures?
- Were the relevant tests actually run, and are any remaining checks clearly listed?
A reusable AI debugging brief
Copy the structure and replace the brackets with your own code and context. Remove credentials and include what is needed to reproduce the issue.
Task: [Explain, reproduce, debug or review a specific issue.]
Environment: [Language/runtime version, module system and relevant framework.]
Code: [Minimum relevant code or permitted files; remove secrets.]
Failure: [Exact error/stack or observed wrong result and steps to reproduce.]
Expected: [The correct result for the same input.]
Preserve: [Interfaces, working behavior and files outside scope.]
Checks: [Existing tests, edge cases and the finite command to run.]
Done means: [Actual changed files, check results and anything incomplete.]Choose the workspace for your code
Use Chat to discuss a snippet, or Work to create files and run supported checks. Work requires Plus. Supply permitted code or an authorized project connection; a cloud workspace does not automatically contain your local repository. Relevant code and context may reach the selected provider.
AI coding and debugging questions
Use the answers to choose a method and a check you can perform.
What should I include when asking AI to debug code?
Give the language/runtime and framework, minimal relevant code, exact error or wrong result, reproduction steps and expected behavior. Include existing tests and explain what must stay unchanged.
Does a Chat answer prove the code was run?
No. A suggested command or confident explanation is not an executed check. Work can use supported workspace tools; inspect its actual files and results, then verify the important checks yourself.
Can I use AI for code review?
Provide a permitted snippet or diff and its requirements. Ask for specific problems, reproducing inputs and useful tests, then check the findings. The review prompt in this lesson is practice; the real basket run demonstrates debugging, not a complete repository or security review.
Do nine passing tests prove that the code is correct?
They establish the behavior covered by those nine cases. Other input shapes, overflow, integration and security properties need their own checks. Keep the exact tested code and environment visible.
Do I need Plus to get code help?
Code discussion in Chat follows the selected model and account’s access/usage. Running a Work task requires Plus or Plus Premium and uses credits; reading this lesson does not.
Guides and resources
Find more detail and choose your next step.
- Start a Work taskLearn more
- Work controls and accessLearn more
- Project folders and permissionsLearn more
- Give useful contextLearn more
- Focused follow-upsLearn more
- Reusable Work rulesLearn more
- Choose a modelLearn more
- Developer use casesLearn more
- Node.js test runner referenceLearn more
- Node.js assertion referenceLearn more
Your turn
Reproduce the failure and test the fix.
Supply the complete broken function and four tests below in Work. Inspect the baseline failure and smallest fix before adding the validation requirement.
Write a draft and review the checklist.
Your draft saves in this browser. You can leave and come back.
Take the brief into Work
Copy the brief, open Gab AI and choose Work before pasting and sending it. Open the delivered file and check it against the brief.
These buttons open the product and copy your draft. You choose the mode and send the request yourself.
Open Gab AI for WorkMake one change and check the whole result
Review the first answer, then send this follow-up in the same conversation.
Revise only this basket project. Reject a negative or non-integer quantity or unitCents with a RangeError. A quantity of zero is valid. Keep totalCents and the CommonJS export, preserve the original four tests byte-for-byte, and add tests for negative quantity, fractional quantity, negative unitCents, fractional unitCents, and a zero unitCents line. Run the full nine-test suite and record the actual result in DEBUGGING.md. Deliver the complete revised source, test file and notes. No external dependencies, browsing, connected accounts, publishing or deployment. Do not describe this bounded validation as comprehensive security or all possible input validation.Check that the requested change happened and the correct facts, format and missing details survived. For a file, open the revised artifact and inspect nearby paragraphs or formulas too.
