{"record":{"id":"af1f5276e3d67913","repo":"windmill-labs/windmill","slug":"multiple-error-contexts-provided","errorCode":null,"errorMessage":"Multiple error contexts provided","messagePattern":"Multiple error contexts provided","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/copilot/chat/shared.ts","lineNumber":418,"sourceCode":"\tlet workspaceItemsContext = ''\n\n\tlet result = '\\n\\n'\n\tfor (const context of selectedContext) {\n\t\tif (context.type === 'code') {\n\t\t\thasCode = true\n\t\t\tcodeContext += codeTemplate\n\t\t\t\t.replace('{title}', context.title)\n\t\t\t\t.replace('{language}', scriptLangToEditorLang(context.lang))\n\t\t\t\t.replace(\n\t\t\t\t\t'{code}',\n\t\t\t\t\tapplyCodePieceToCodeContext(\n\t\t\t\t\t\tselectedContext.filter((c) => c.type === 'code_piece'),\n\t\t\t\t\t\tcontext.content\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t} else if (context.type === 'error') {\n\t\t\tif (hasError) {\n\t\t\t\tthrow new Error('Multiple error contexts provided')\n\t\t\t}\n\t\t\thasError = true\n\t\t\terrorContext = errorContext.replace('{error}', context.content)\n\t\t} else if (context.type === 'db') {\n\t\t\thasDb = true\n\t\t\tdbContext += dbTemplate\n\t\t\t\t.replace('{title}', context.title)\n\t\t\t\t.replace('{schema}', context.schema?.stringified ?? 'to fetch with get_db_schema')\n\t\t\tdbContext += '\\n'\n\t\t} else if (context.type === 'diff') {\n\t\t\thasDiff = true\n\t\t\tconst diff = JSON.stringify(context.diff)\n\t\t\tdiffContext += (diff.length > 3000 ? diff.slice(0, 3000) + '...' : diff) + '\\n'\n\t\t} else if (context.type === 'flow_module') {\n\t\t\thasFlowModule = true\n\t\t\tflowModuleContext += `${context.id}\\n`\n\t\t} else if (context.type === 'workspace_script') {\n\t\t\tif (!workspaceItemsContext) {","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/copilot/chat/shared.ts#L400-L436","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Send only the most relevant error context; drop or merge the others before starting the chat.","Concatenate multiple error messages into a single error-context string instead of two separate items.","Filter the selected context array: keep the first (or latest) item where c.type === 'error'.","Wrap context construction in a check that counts error-typed items and reduces them to one."],"exampleFix":"// before\nconst ctx = [{ type: 'error', content: errA }, { type: 'error', content: errB }]\n// after\nconst errors = ctx.filter((c) => c.type === 'error')\nconst merged = [{ type: 'error', content: errors.map((e) => e.content).join('\\n---\\n') }]","handlingStrategy":"validation","validationCode":"const errorItems = selectedContext.filter((c) => c.type === 'error')\nif (errorItems.length > 1) {\n  selectedContext = [\n    ...selectedContext.filter((c) => c.type !== 'error'),\n    { type: 'error', content: errorItems.map((e) => e.content).join('\\n\\n') }\n  ]\n}","typeGuard":"function isErrorContext(c: unknown): c is { type: 'error'; content: string } {\n  return !!c && typeof c === 'object' && (c as any).type === 'error' && typeof (c as any).content === 'string'\n}","tryCatchPattern":"try {\n  const ctx = buildContextString(context)\n} catch (e) {\n  if (e.message === 'Multiple error contexts provided') {\n    // dedupe to one error item and rebuild\n  }\n}","preventionTips":["Enforce single-selection of error context in the UI before sending to chat.","Merge error strings into one context item when batch operations fail.","Add a reducer/dedupe step whenever context arrays are assembled programmatically.","Log a warning (not throw) at selection time when more than one error is picked."],"tags":["copilot","context-building","input-validation"],"backgroundTag":"invalid-input","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}