different-ai/openwork · error · Error
Automation cancellation response was invalid.
Error message
Automation cancellation response was invalid.
What it means
useCancelAutomationRun POSTs /v1/automation-runs/{runId}/cancel and expects a 2xx body containing the updated run. If the body is not an object or lacks the run field, this error is thrown. The mutation uses useAutomationMutation, so the error surfaces in the mutation's error state rather than crashing.
Source
Thrown at ee/apps/den-web/app/(den)/dashboard/_components/automation-data.tsx:127
{ method: "POST" },
)),
);
}
export function useArchiveAutomation() {
return useAutomationMutation<string, ReturnType<typeof automationDetailSchema.parse>>(
async (automationId) => automationDetailSchema.parse(await payload(
`/v1/automations/${encodeURIComponent(automationId)}`,
{ method: "DELETE" },
)),
);
}
export function useCancelAutomationRun() {
return useAutomationMutation<string, ReturnType<typeof automationRunSchema.parse>>(
async (runId) => {
const value = await payload(`/v1/automation-runs/${encodeURIComponent(runId)}/cancel`, { method: "POST" });
if (typeof value !== "object" || value === null || !("run" in value)) throw new Error("Automation cancellation response was invalid.");
return automationRunSchema.parse(value.run);
},
);
}
View on GitHub (pinned to 2b7df46e8a)
Solutions
- Inspect the cancel response body and compare with the expected {run:{...}} shape.
- Handle already-completed runs server-side by returning the run in a terminal state instead of an empty body.
- Update client unwrapping if the server now uses an envelope.
- Retry: if the run already finished, the cancel is a no-op — refresh runs via query invalidation instead.
Example fix
// before
if (typeof value !== "object" || value === null || !("run" in value)) throw new Error("Automation cancellation response was invalid.");
// after
const run = (value as { run?: unknown })?.run;
if (run === undefined && (value as { status?: string })?.status === "already_finished") {
return null; // treat as no-op
}
if (run === undefined) throw new Error("Automation cancellation response was invalid."); Defensive patterns
Strategy: type-guard
Validate before calling
const value = await payload(`/v1/automation-runs/${encodeURIComponent(runId)}/cancel`, { method: "POST" });
if (!hasRun(value)) { /* treat as inconclusive; refetch run state */ } Type guard
function hasRun(v: unknown): v is { run: unknown } {
return typeof v === "object" && v !== null && "run" in v;
} Try / catch
const cancelRun = useCancelAutomationRun();
cancelRun.mutate(runId, {
onError: (err) => {
if (err instanceof Error && err.message.includes("cancellation response was invalid")) {
// inconclusive: poll run status instead of assuming failure
refetchRun(runId);
}
},
}); Prevention
- Treat cancel as idempotent and confirm via polling the run status afterward.
- Add server contract tests for the cancel endpoint including the already-finished case.
- Return the run object even when the run already completed.
- Use onError (not throw) so the runs list can refresh to the authoritative state.
When it happens
Trigger: Cancel endpoint returns 200/202 with an empty body or only {status:"cancelling"}; envelope reshaped by the server or a proxy; run already finished so the server returns a success body without the run object.
Common situations: Server/client version mismatch; run completed before the cancel arrived and the handler short-circuits with an empty 200; intermediate proxy stripping the body on 202.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- Automation run response was invalid.
- Automation run history was invalid.
- Den returned an invalid diagnostics configuration response.
- Den returned an invalid egress diagnostic result.
- Task creation did not return a session ID.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/87242c93d3a2d624.
Report an issue: GitHub.