FlowDrop Workflow Specification 1.0-draft

A generic failure is a last resort, never a design

A catch-all failure answer is a reporting device. Where it stands in for a refusal the door could have named, it renders "this endpoint has never worked" indistinguishable from "the server hiccupped".

The rule

Normative: this is the rule
  1. A failure an implementation cannot attribute to a specific cause is answered with a fixed generic message; the underlying failure's own message is logged and never reaches the response body.
  2. A failure an implementation can classify must be answered as that classification (a client error as a client error, a refusal by the name the door has for it), and a generic server failure must never stand in for a refusal the door is able to name.

What it means

A generic failure message exists for the case an implementation genuinely cannot name: something broke, and nothing about the failure tells the door which refusal it should have been. That message is a last resort, not a convenience. Anything a door can attribute — a record that does not exist, a caller without the permission it needed, a body that failed the shared gate — must be answered as that specific thing, never folded into the same catch-all just because the code path happens to have one.

The two failures read identically to a caller who only sees a status and a message that says nothing: "this has never worked" and "something broke just now" become indistinguishable. The underlying cause still belongs in the log; only the caller-facing body is generic, and only when nothing more specific was knowable.

Example

The same route answers a missing record and a denied one differently — neither collapses into the other's message.

A pipeline id nothing matches404 — refused
GET /api/flowdrop/pipeline/{pipeline}/logs

{"success": false, "error": "Pipeline with ID 99999 does not exist."}
The same route, denied to a caller with no permission on it403 — refused
GET /api/flowdrop/pipeline/{pipeline}/logs

{"success": false, "error": "Access denied"}

Nothing this door cannot attribute to one of these is answered any other way: it gets the one fixed message, and the detail stays in the log.

Rule identifiers are permanent and are never renumbered. Each implementation publishes its own standing against these rules; this specification does not.spec 1.0-draft · API-7 · changed in spec 1.0