{"record":{"id":"3c883f204ccede91","repo":"windmill-labs/windmill","slug":"failed-to-execute-test-run-errormessage","errorCode":null,"errorMessage":"Failed to execute test run: ${errorMessage}","messagePattern":"Failed to execute test run: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/copilot/chat/shared.ts","lineNumber":1829,"sourceCode":"\t\t// hosts that wire the job hooks) — don't advertise it to in-editor chats.\n\t\tif (detachEnabled && config.contextName === 'flow' && !job.success) {\n\t\t\treturn (\n\t\t\t\tsummary +\n\t\t\t\t`\\n\\nFor per-step statuses and results (subflow steps included), call get_flow_run_details with id=\"${jobId}\".`\n\t\t\t)\n\t\t}\n\t\treturn summary\n\t} catch (error) {\n\t\t// formatToolError, not `error.message`: the generated client puts the server's\n\t\t// message in `body` and leaves `message` as the bare status text, so a path\n\t\t// runnable aimed at an undeployed flow reported \"Not Found\" instead of naming\n\t\t// the flow it could not find — losing the one diagnostic the run exists for.\n\t\tconst errorMessage = formatToolError(error)\n\t\tconfig.toolCallbacks.setToolStatus(config.toolId, {\n\t\t\tcontent: `Test execution failed`,\n\t\t\terror: errorMessage\n\t\t})\n\t\tthrow new Error(`Failed to execute test run: ${errorMessage}`)\n\t}\n}\n\ntype FlowStepScriptLoader = (\n\tmoduleValue: { path: string; hash?: string },\n\tworkspace: string\n) => Promise<{ content: string; language: ScriptLang }>\n\ntype FlowStepPreviewLoader = (path: string, workspace: string) => Promise<FlowValue | undefined>\n\nexport type FlowStepTestRunConfig = {\n\tflowValue: FlowValue\n\tstepId: string\n\targs?: Record<string, any> | null\n\tworkspace: string\n\ttoolCallbacks: ToolCallbacks\n\ttoolId: string\n\tbackground?: boolean","sourceCodeStart":1811,"sourceCodeEnd":1847,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/copilot/chat/shared.ts#L1811-L1847","documentation":"The test-run tool catches any error raised while launching or awaiting a test execution (queueing the job, building args, polling failures, transport errors) and rethrows it as 'Failed to execute test run: <message>' using formatToolError for a readable cause. The same text is pushed to the tool status so the model can react. It preserves the underlying diagnostic instead of losing it.","triggerScenarios":"executeTestRun's internal steps threw: the run creation API call failed (network/401/permission), the flow or script referenced by the test could not be found, buildTestRunArgs raised, or the polling helper threw (including the 60s timeout error from the same file).","commonSituations":"Expired or missing workspace auth so the run API returns 401/403; the script path changed or was deleted since the chat started; backend temporarily unreachable; workspace archived; the underlying cause is the test-timeout error surfacing through this wrapper.","solutions":["Read the suffix after 'Failed to execute test run:' for the actual cause and address it (auth, path, network, timeout).","If the cause mentions a missing script/flow, re-open the correct file and retry so the chat context refreshes its path/hash.","Check you are authenticated to the right workspace (re-login or fix the token) if the cause is 401/403.","If the cause is a timeout, see the timeout remedy: optimize the code or check worker availability.","Retry once if the cause is transient (network/5xx); check backend health if it persists."],"exampleFix":"// before\nawait testRun({ path: 'old/script/path.ts' }) // path deleted\n// after\nconst current = await workspace.getScriptByPath('scripts/current.ts')\nawait testRun({ path: current.path })","handlingStrategy":"try-catch","validationCode":"const path = scriptOptions?.path\nif (!path || !(await workspace.scriptExists(path))) {\n  throw new Error(`Refusing test run: script ${path} no longer exists`) // avoid deeper failure\n}\nif (!workspace.isAuthenticated()) await workspace.login()","typeGuard":"function isTestRunError(e: unknown): e is Error & { message: `Failed to execute test run: ${string}` } {\n  return e instanceof Error && e.message.startsWith('Failed to execute test run:')\n}","tryCatchPattern":"try {\n  await executeTestRun(config)\n} catch (e) {\n  if (isTestRunError(e)) {\n    const cause = e.message.slice('Failed to execute test run: '.length)\n    // branch on cause: 401 -> re-auth; not found -> refresh path; timeout -> optimize\n  }\n}","preventionTips":["Confirm workspace auth is valid before starting test runs.","Re-open the script/flow after renames so the chat context holds the current path/hash.","Check backend reachability/health when running against a local dev instance.","Treat the embedded cause message as the primary diagnostic and route on it."],"tags":["test-run","copilot","api-error"],"backgroundTag":"tool-execution-failed","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"}