windmill-labs/windmill · error
No code block found
Error message
No code block found
What it means
After extracting fenced code blocks from an AI completion, the code generator asserts the extracted code string is non-empty and throws 'No code block found' otherwise. generatedCode is set first so the UI shows whatever (empty) extraction happened. It means the model reply contained no usable code block.
Source
Thrown at frontend/src/lib/components/copilot/lib.ts:1539
// partial code block, keep going
match = response.match(/```[a-zA-Z]+\n([\s\S]*)/)
if (!match) {
continue
}
code = match[1]
if (!code.endsWith('`')) {
// skip displaying if possible that part of three ticks (end of code block)s
generatedCode.set(code)
}
}
// make sure we display the latest and complete code
generatedCode.set(code)
if (code.length === 0) {
throw new Error('No code block found')
}
return code
}
View on GitHub (pinned to e474e8803c)
Solutions
- Retry generation — transient/truncated replies often succeed on a second attempt.
- Rephrase the prompt to explicitly request code only, and check the script/flow kind matches the requested language.
- Increase max output tokens or use a stronger model if the reply is being cut off.
- Inspect the shown chat message to see whether the model refused or errored, and address that cause.
- Check provider/credential health — a proxy error page can come back as plain text with no code.
Example fix
// before
const code = await generateCode(prompt) // throws when model returns prose
// after
let code
try {
code = await generateCode(prompt)
} catch (e) {
if (e.message === 'No code block found') {
code = await generateCode(prompt + '\nRespond ONLY with a fenced code block.')
} else { throw e }
} Defensive patterns
Strategy: retry
Validate before calling
function extractCodeBlock(reply: string): string | null {
const m = reply.match(/```[\w]*\n([\s\S]*?)```/)
return m && m[1].trim() ? m[1] : null
} Type guard
function hasCodeBlock(reply: string): boolean {
return /```[\w]*\n[\s\S]+?```/.test(reply)
} Try / catch
try {
code = await generateCode(prompt)
} catch (e) {
if (e.message === 'No code block found') {
// inspect the raw reply for a refusal, then retry once with a stricter prompt
code = await generateCode(prompt + '\nRespond ONLY with one fenced code block.')
} else throw e
} Prevention
- End generation prompts with an instruction to output only a fenced code block.
- Check the raw reply for refusals/errors before attempting extraction.
- Raise max output tokens to avoid truncated (unclosed) code fences.
- Retry once automatically on empty extraction.
When it happens
Trigger: The AI response contained no fenced code block or the extraction regex matched zero/empty content — e.g. the model answered with prose only, a refusal, or an empty completion; also when the streaming reply was truncated before any code fence closed.
Common situations: Model refused the request (policy/safety) and returned an explanation; prompt asked a question instead of requesting code; provider returned an error message rendered as text; max_tokens cut the response before the code block.
Related errors
- AI response was empty
- AI response contained empty code block
- AI response did not contain valid code. Please try rephrasin
- Invalid JSON after replacement: ${message}
- no policy could be derived for runnable(s) ${malformed.join(
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/bb1fffe69ffdadd3.
Report an issue: GitHub.