Skip to main content
← Back to list
01Issue
BugShippedSwamp CLIPublic
Assigneeszack

Relationships

#3773 A coded UserError a model method throws reaches a workflow step without its code, because InProcessExecutor keeps only the message

Opened by zack · 10/22/2026· Shipped 10/22/2026

Problem

swamp-club#3748 records a failed workflow step's stable error code: the job loop in WorkflowExecutionService reads error instanceof UserError ? error.code : undefined and puts it on the step_failed event, the StepRun record and swamp workflow run --json. That works for a UserError swamp throws itself, such as the evaluated_cache_holds_sensitive_arguments refusal. It never works for a coded UserError that a model method's own execute throws.

InProcessExecutor.execute (src/domain/models/in_process_executor.ts, both catch branches) turns the thrown error into { status: "error", error: error.message, errorPaths }. MethodExecutionService then rethrows new Error(executionResult.error) with the paths and data handles attached. The class and the code are gone before DefaultStepExecutor sees the error, so the step records no errorCode.

Found while porting swamp-club#3746: a scratch integration run had a model method throw new UserError("intentional failure plain", "auth_failed") with no secret in it, and the step still recorded errorCode: undefined. The #3748 unit test passes because it drives a fake StepExecutor that rejects with the UserError directly, bypassing the in-process path.

Fix

  • InProcessExecutor: carry the thrown error's code in the error result, as errorPaths is carried, when the error is a UserError with a code.
  • MethodExecutionService: rethrow a UserError with that code (keeping the marked paths and the attached data handles) when the result carries one, and a plain Error otherwise.
  • Check whether the remote-execution result path (the worker runner protocol) needs the same field.

Files

  • src/domain/models/in_process_executor.ts
  • src/domain/models/method_execution_service.ts
  • the executor result type the two share

Tests

  • in_process_executor_test.ts: a method that throws a coded UserError yields an error result with its code; an uncoded or plain error yields none.
  • An integration test through the real WorkflowExecutionService and DefaultStepExecutor: a model method that throws new UserError(..., "auth_failed") gives the step errorCode: "auth_failed" on the step_failed event and the run record.
02Bog Flow
✓OPEN✓TRIAGED✓IN PROGRESS✓SHIPPED+ 1 MOREASSIGNED+ 5 MOREREVIEW+ 20 MOREPR_LINKED+ 2 MORESESSION_SUMMARIZED

Shipped

10/22/2026, 3:45:40 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
zack assigned zack10/22/2026, 1:45:41 PM

Sign in to post a ripple.