windmill-labs/windmill · error

Multiple error contexts provided

Error message

Multiple error contexts provided

What it means

When building the prompt context string, buildContextString enforces that at most one context item of type 'error' is supplied. If a second error-typed context is encountered while one has already been processed, it throws 'Multiple error contexts provided'. The single error slot is substituted into the '{error}' template.

Source

Thrown at frontend/src/lib/components/copilot/chat/shared.ts:418

	let workspaceItemsContext = ''

	let result = '\n\n'
	for (const context of selectedContext) {
		if (context.type === 'code') {
			hasCode = true
			codeContext += codeTemplate
				.replace('{title}', context.title)
				.replace('{language}', scriptLangToEditorLang(context.lang))
				.replace(
					'{code}',
					applyCodePieceToCodeContext(
						selectedContext.filter((c) => c.type === 'code_piece'),
						context.content
					)
				)
		} else if (context.type === 'error') {
			if (hasError) {
				throw new Error('Multiple error contexts provided')
			}
			hasError = true
			errorContext = errorContext.replace('{error}', context.content)
		} else if (context.type === 'db') {
			hasDb = true
			dbContext += dbTemplate
				.replace('{title}', context.title)
				.replace('{schema}', context.schema?.stringified ?? 'to fetch with get_db_schema')
			dbContext += '\n'
		} else if (context.type === 'diff') {
			hasDiff = true
			const diff = JSON.stringify(context.diff)
			diffContext += (diff.length > 3000 ? diff.slice(0, 3000) + '...' : diff) + '\n'
		} else if (context.type === 'flow_module') {
			hasFlowModule = true
			flowModuleContext += `${context.id}\n`
		} else if (context.type === 'workspace_script') {
			if (!workspaceItemsContext) {

View on GitHub (pinned to e474e8803c)

Solutions

  1. Send only the most relevant error context; drop or merge the others before starting the chat.
  2. Concatenate multiple error messages into a single error-context string instead of two separate items.
  3. Filter the selected context array: keep the first (or latest) item where c.type === 'error'.
  4. Wrap context construction in a check that counts error-typed items and reduces them to one.

Example fix

// before
const ctx = [{ type: 'error', content: errA }, { type: 'error', content: errB }]
// after
const errors = ctx.filter((c) => c.type === 'error')
const merged = [{ type: 'error', content: errors.map((e) => e.content).join('\n---\n') }]
Defensive patterns

Strategy: validation

Validate before calling

const errorItems = selectedContext.filter((c) => c.type === 'error')
if (errorItems.length > 1) {
  selectedContext = [
    ...selectedContext.filter((c) => c.type !== 'error'),
    { type: 'error', content: errorItems.map((e) => e.content).join('\n\n') }
  ]
}

Type guard

function isErrorContext(c: unknown): c is { type: 'error'; content: string } {
  return !!c && typeof c === 'object' && (c as any).type === 'error' && typeof (c as any).content === 'string'
}

Try / catch

try {
  const ctx = buildContextString(context)
} catch (e) {
  if (e.message === 'Multiple error contexts provided') {
    // dedupe to one error item and rebuild
  }
}

Prevention

When it happens

Trigger: selectedContext (or another context source passed to the chat) contains two or more items with type === 'error' — e.g. the user selected multiple failed run logs, or code stitched several error objects into the context array before calling the chat.

Common situations: User multi-selects several failed runs in the run list and sends them as context; a caller accumulates error contexts across retries in the same array; an integration forwards both a run error and a job error into the same selection.

Related errors


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