different-ai/openwork · error · Error

Automation run response was invalid.

Error message

Automation run response was invalid.

What it means

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.

Source

Thrown at ee/apps/den-web/app/(den)/dashboard/_components/automation-data.tsx:70

      return status && ["queued", "claimed", "running"].includes(status) ? 2_000 : false;
    },
  });
}

export function useAutomationArtifactSnapshot(configObjectId: string | null, receiptId: string | null) {
  return useQuery({
    queryKey: ["workflow", configObjectId, "snapshot", receiptId],
    queryFn: async () => workflowArtifactSnapshotSchema.parse(await payload(`/v1/workflows/${encodeURIComponent(configObjectId ?? "")}/snapshots/${encodeURIComponent(receiptId ?? "")}`)),
    enabled: Boolean(configObjectId && receiptId),
  });
}

export function useRunAutomationNow() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async (automationId: string) => {
      const value = await payload(`/v1/automations/${encodeURIComponent(automationId)}/run`, { method: "POST" });
      if (typeof value !== "object" || value === null || !("run" in value)) throw new Error("Automation run response was invalid.");
      return automationRunSchema.parse(value.run);
    },
    onSuccess: async () => queryClient.invalidateQueries({ queryKey: ["automations"] }),
  });
}

export function useCreateCloudAutomation() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async (definition: CreateCloudAutomation) => automationDetailSchema.parse(await payload("/v1/cloud-automations", {
      method: "POST",
      body: JSON.stringify(definition),
    })),
    onSuccess: async () => queryClient.invalidateQueries({ queryKey: ["automations"] }),
  });
}

function useAutomationMutation<TInput, TResult>(mutationFn: (input: TInput) => Promise<TResult>) {

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Inspect the raw response body in devtools and compare with the expected {run:{...}} shape.
  2. Update the client to unwrap envelopes if the server response shape changed.
  3. Verify server and client versions match; redeploy the stale side.
  4. Check the server logs for the /run handler to see what it returned and why.

Example fix

// before
if (typeof value !== "object" || value === null || !("run" in value)) throw new Error("Automation run response was invalid.");
// after
const run = (value as { run?: unknown; data?: { run?: unknown } })?.run ?? (value as { data?: { run?: unknown } })?.data?.run;
if (run === undefined) throw new Error("Automation run response was invalid.");
return automationRunSchema.parse(run);
Defensive patterns

Strategy: type-guard

Validate before calling

const value = await payload(`/v1/automations/${encodeURIComponent(automationId)}/run`, { method: "POST" });
if (!hasRun(value)) { /* don't parse; show retry */ }

Type guard

function hasRun(v: unknown): v is { run: unknown } {
  return typeof v === "object" && v !== null && "run" in v;
}

Try / catch

const runNow = useRunAutomationNow();
runNow.mutate(id, {
  onError: (err) => {
    if (err instanceof Error && err.message === "Automation run response was invalid.") {
      showToast("Run started but details unavailable — check history.");
      queryClient.invalidateQueries({ queryKey: ["automations"] });
    }
  },
});

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/f5f766647dd73393. Report an issue: GitHub.