{"record":{"id":"f5f766647dd73393","repo":"different-ai/openwork","slug":"automation-run-response-was-invalid","errorCode":null,"errorMessage":"Automation run response was invalid.","messagePattern":"Automation run response was invalid\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ee/apps/den-web/app/(den)/dashboard/_components/automation-data.tsx","lineNumber":70,"sourceCode":"      return status && [\"queued\", \"claimed\", \"running\"].includes(status) ? 2_000 : false;\n    },\n  });\n}\n\nexport function useAutomationArtifactSnapshot(configObjectId: string | null, receiptId: string | null) {\n  return useQuery({\n    queryKey: [\"workflow\", configObjectId, \"snapshot\", receiptId],\n    queryFn: async () => workflowArtifactSnapshotSchema.parse(await payload(`/v1/workflows/${encodeURIComponent(configObjectId ?? \"\")}/snapshots/${encodeURIComponent(receiptId ?? \"\")}`)),\n    enabled: Boolean(configObjectId && receiptId),\n  });\n}\n\nexport function useRunAutomationNow() {\n  const queryClient = useQueryClient();\n  return useMutation({\n    mutationFn: async (automationId: string) => {\n      const value = await payload(`/v1/automations/${encodeURIComponent(automationId)}/run`, { method: \"POST\" });\n      if (typeof value !== \"object\" || value === null || !(\"run\" in value)) throw new Error(\"Automation run response was invalid.\");\n      return automationRunSchema.parse(value.run);\n    },\n    onSuccess: async () => queryClient.invalidateQueries({ queryKey: [\"automations\"] }),\n  });\n}\n\nexport function useCreateCloudAutomation() {\n  const queryClient = useQueryClient();\n  return useMutation({\n    mutationFn: async (definition: CreateCloudAutomation) => automationDetailSchema.parse(await payload(\"/v1/cloud-automations\", {\n      method: \"POST\",\n      body: JSON.stringify(definition),\n    })),\n    onSuccess: async () => queryClient.invalidateQueries({ queryKey: [\"automations\"] }),\n  });\n}\n\nfunction useAutomationMutation<TInput, TResult>(mutationFn: (input: TInput) => Promise<TResult>) {","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-web/app/(den)/dashboard/_components/automation-data.tsx#L52-L88","documentation":"useRunAutomationNow POSTs /v1/automations/{id}/run and expects a 2xx body containing a run object. If the body is not an object or lacks the run field, this error is thrown before Zod parsing. It signals the run was accepted (or at least responded 2xx) but the client cannot extract run details.","triggerScenarios":"Server returns 200 with an empty body or {accepted:true} without the run object; envelope change ({data:{run:...}}); the automation is in a state where the server responds success without a run.","commonSituations":"Older Den server version responding with a legacy ack-only body; reverse proxy transforming responses; race where the automation was disabled between click and request.","solutions":["Inspect the raw response body in devtools and compare with the expected {run:{...}} shape.","Update the client to unwrap envelopes if the server response shape changed.","Verify server and client versions match; redeploy the stale side.","Check the server logs for the /run handler to see what it returned and why."],"exampleFix":"// before\nif (typeof value !== \"object\" || value === null || !(\"run\" in value)) throw new Error(\"Automation run response was invalid.\");\n// after\nconst run = (value as { run?: unknown; data?: { run?: unknown } })?.run ?? (value as { data?: { run?: unknown } })?.data?.run;\nif (run === undefined) throw new Error(\"Automation run response was invalid.\");\nreturn automationRunSchema.parse(run);","handlingStrategy":"type-guard","validationCode":"const value = await payload(`/v1/automations/${encodeURIComponent(automationId)}/run`, { method: \"POST\" });\nif (!hasRun(value)) { /* don't parse; show retry */ }","typeGuard":"function hasRun(v: unknown): v is { run: unknown } {\n  return typeof v === \"object\" && v !== null && \"run\" in v;\n}","tryCatchPattern":"const runNow = useRunAutomationNow();\nrunNow.mutate(id, {\n  onError: (err) => {\n    if (err instanceof Error && err.message === \"Automation run response was invalid.\") {\n      showToast(\"Run started but details unavailable — check history.\");\n      queryClient.invalidateQueries({ queryKey: [\"automations\"] });\n    }\n  },\n});","preventionTips":["Assert the /run response shape in server contract tests.","Use mutation onError to keep the UI functional when the payload is malformed.","Invalidate the automations queries even on this error — the run may exist despite a malformed response.","Keep automationRunSchema and server DTO versions aligned."],"tags":["api-contract","zod","automations"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}