Debugging AI-Generated Code
20 minIntermediateHTML · CSS · JS
In this lesson
- ▸Use a repeatable loop: reproduce, read, hypothesise, test, fix
- ▸Read an error message and know which line to look at first
- ▸Fix off-by-one, boundary, sorting and async-ordering bugs
The big idea
Debugging generated code is the same as debugging your own — except you didn't build the mental model while writing it. So build it now: read the evidence, guess one cause, test that guess, change one thing.
The class-results page in the editor was "generated" from a clear prompt. Look at the preview: an empty table, NaN as the average, nothing for the top student — and one line in the console. Four different bugs are hiding here, and only one of them produces an error message.
A debugging loop that works
- Reproduce — see the bug yourself, every time. Note the exact input.
- Read — the error's type, message and location. Read the first error first; later ones are often side effects.
- Hypothesise — one specific guess: "
bestis undefined becausestudentsis still empty whenrenderruns". - Test the guess — a
console.logbefore the failing line proves or kills it in seconds. - Fix one thing, re-run. Changing five things at once tells you nothing about which one mattered.
Render failed: TypeError: Cannot read properties of undefined (reading 'name')Translate it: "something was undefined, and the code tried to read .name from it." Search the code for .name — only a few lines qualify.
No error doesn't mean no bug
NaN, a wrong grade or the wrong "top student" never throw. JavaScript happily computes nonsense. Compare outputs against the requirements, not against "did it crash?".
Four patterns to recognise
What the assistant wrote
for (let i = 0; i <= scores.length; i++) // one step too far
if (score > 80) return "A"; // 80 should be an A
scores.sort(); // sorts as text: 100 < 49What a reviewer ships
for (let i = 0; i < scores.length; i++)
if (score >= 80) return "A";
Math.max(...scores); // numeric, doesn't reorder<= reads scores[scores.length], which is undefined, and total + undefined is NaN. Without a compare function, sort() converts numbers to strings — and it also reorders the original array.
Async ordering bug
let students = [];
fetch("students.json")
.then((r) => r.json())
.then((data) => { students = data; });
render(students); // runs NOW, data arrives LATERRender after the data arrives
async function loadAndRender() {
const response = await fetch("students.json");
const students = await response.json();
render(students);
}
loadAndRender();fetch returns immediately with a promise. Code on the next line runs before the response exists. Anything that needs the data must run after it arrives.
Asking the assistant for help debugging
Give it the evidence: the exact error, the code around the line, what you expected, and what you already ruled out. Ask for the most likely cause and how to confirm it before any fix.
average([80, 90, 70]) should be 80, but it returns NaN. Add a console.log inside the loop to watch i and scores[i], find the extra step, and fix the loop. Don't rewrite the function — fix the bug.
Checks
- average() returns the right number
Check understanding
What you learned
- ✓Reproduce → read → hypothesise → test the guess → fix one thing.
- ✓Read the first error first; translate it into plain words.
- ✓Silent bugs (
NaN, wrong boundaries, text sorting) need you to compare output with the spec. - ✓Anything that uses fetched data must run after the data arrives.
Console output from your code appears here.