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

  1. Retry generation — transient/truncated replies often succeed on a second attempt.
  2. Rephrase the prompt to explicitly request code only, and check the script/flow kind matches the requested language.
  3. Increase max output tokens or use a stronger model if the reply is being cut off.
  4. Inspect the shown chat message to see whether the model refused or errored, and address that cause.
  5. 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

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-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/bb1fffe69ffdadd3. Report an issue: GitHub.