proto/server: 88 Connect errors carry a message and no detail, `RunResponse.Error.kind` is a free string, and `MutationResult` is a CLI document living in the RPC package
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 9
- Forks
- 0
- Avg merge
- 3h 3m
- Merged PRs (30d)
- 509
Description
Observed behavior
At eb8172f, pkg/flowstate/v1/server/*.go has 88 connect.NewError sites (56 InvalidArgument, 11 PermissionDenied, 10 Internal, 7 FailedPrecondition) and none attaches an error detail. connect.NewErrorDetail appears only in the plugin SDK (plugin/sdk/errors.go:212,248), so the plugin protocol has typed refusals and the public control plane has prose. A client cannot distinguish "input failed declaration binding" from "size limit exceeded" from "tenant not addressable" without parsing a sentence, which is what cmd/flow and the MCP layer do today, and what #1552 is fixing on the CLI side one refusal at a time.
Validate and Compile return DiagnosticReport in the success body, which is right. Run refuses a bad spec with a bare InvalidArgument string, so the same class of problem reaches a caller two ways. RunResponse.Error.kind (service.proto:155) is deliberately an un-enumerated string mirroring a Go type, so a caller branching on it is matching text against Go source.
MutationResult (service.proto:1332-1400) is defined in the service package and returned by no RPC: every constructor is in cmd/flow (lifecycle.go:45,99, signals.go:393, schedule.go:271-385), and Cancel, Terminate and Signal still return empty messages. The proto comment cites #374 for the richer responses.
Desired outcome
- One
flowstate.v1.ErrorDetailmessage attached to every refusal the server produces: a stablecode(theDiagnosticcode vocabulary where the refusal is about a file, a small closed set otherwise), an optional field path, and an optionalDiagnosticwhen the refusal is a compile-class problem.RunResponse.Error.kindbecomes an enum projected fromErrorKind. - The CLI and the MCP layer render from the detail, so #1552's per-refusal typing collapses to one renderer.
Cancel,Terminate,Signal, and the schedule mutations return theMutationResultthe CLI already prints, produced by the server, so the document a script indexes is the server's word rather than the client's inference.
Acceptance criteria
- A test asserts every
connect.NewErrorreturned by aWorkflowServicehandler carries anErrorDetail; the count of sites without one is zero and pinned. flow run -o jsonon a refused submit prints a document withcodeand no prose trailer (#1552's acceptance).flow cancel -o jsonprints the server'sMutationResultunchanged.
Constraints and dependencies
- Additive:
kindstays a string until the enum lands beside it, per the repo's carry-both rule. - Adjacent: #184 (the error pipeline), #1552, #374, #1647 (diagnostic codes for type errors).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading service.proto and the handlers under pkg/flowstate/v1/server/*.go, then inspect the existing MutationResult constructors in cmd/flow. Search all connect.NewError sites and the relevant CLI JSON output paths; done means every WorkflowService refusal has an ErrorDetail and the run and cancel acceptance cases expose the server-produced fields unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, backend, cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100