windmill-labs/windmill · error

AI response contained empty code block

Error message

AI response contained empty code block

What it means

In sendInlineRequest, the primary extraction path matches `<new_code>...</new_code>` in the AI reply. If the tag pair exists but the captured content is only whitespace after trimming, no usable code was returned, so this error is thrown.

Source

Thrown at frontend/src/lib/components/copilot/chat/AIChatManager.svelte.ts:2837

					setToolStatus: () => {},
					removeToolStatus: () => {}
				},
				systemMessage
			}

			await this.chatRequest({ ...params })

			// Validate we received a response
			if (!reply.trim()) {
				throw new Error('AI response was empty')
			}

			// Try to extract new code from response
			const newCodeMatch = reply.match(/<new_code>([\s\S]*?)<\/new_code>/i)
			if (newCodeMatch && newCodeMatch[1]) {
				const code = newCodeMatch[1].trim()
				if (!code) {
					throw new Error('AI response contained empty code block')
				}
				return code
			}

			// Fallback: try to take everything after the last <new_code> tag
			const lastNewCodeMatch = reply.match(/<new_code>([\s\S]*)/i)
			if (lastNewCodeMatch && lastNewCodeMatch[1]) {
				const code = lastNewCodeMatch[1].trim().replace(/```/g, '')
				if (!code) {
					throw new Error('AI response contained empty code block')
				}
				return code
			}

			// If no code tags found, throw error with helpful message
			throw new Error('AI response did not contain valid code. Please try rephrasing your request.')
		} catch (error) {
			// if abort controller is aborted, don't throw an error

View on GitHub (pinned to e474e8803c)

Solutions

  1. Retry with a more explicit instruction describing exactly the code to produce.
  2. Select a smaller, well-defined code region so the model has a concrete edit target.
  3. Use a stronger model in the workspace AI settings.
  4. Rephrase the request so it clearly asks for replacement code.

Example fix

// before
const code = await manager.sendInlineRequest('fix this', selected, selection)
// after
const code = await manager.sendInlineRequest(
  'Replace the selected code with a corrected version inside <new_code> tags',
  selected,
  selection
)
Defensive patterns

Strategy: retry

Try / catch

try {
  code = await manager.sendInlineRequest(instr, sel, selection)
} catch (e) {
  if (String(e.message).includes('empty code block')) {
    code = await manager.sendInlineRequest(moreExplicitInstr, sel, selection)
  } else throw e
}

Prevention

When it happens

Trigger: The model emits `<new_code>` open and close tags with nothing (or only whitespace) between them — e.g. the model echoed the tag format without filling in code, or the completion was cut off right after the opening tag.

Common situations: Small/weak model that imitates the prompt's tag format without generating code; response truncated by max_tokens immediately after `<new_code>`; user asked a non-code question in inline mode so the model emitted empty tags.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/94d7898209f646f6. Report an issue: GitHub.