Skip to content

fix: normalize object validation errors#144

Open
0xpolarzero wants to merge 1 commit into
wevm:mainfrom
0xpolarzero:parse-object-validation
Open

fix: normalize object validation errors#144
0xpolarzero wants to merge 1 commit into
wevm:mainfrom
0xpolarzero:parse-object-validation

Conversation

@0xpolarzero
Copy link
Copy Markdown

@0xpolarzero 0xpolarzero commented May 22, 2026

Overview

Normalize validation errors for structured command input.

CLI argv parsing already turns Zod failures into incur's standard VALIDATION_ERROR shape with fieldErrors. HTTP-style execution (split) and MCP-style execution (flat) were using raw Zod .parse(), so the same kind of invalid command input could come back as a generic UNKNOWN error instead.

Issue

Command.execute() has three parsing modes:

  • argv: CLI tokens.
  • split: positional args from argv, options from an object. This is used by HTTP command routes.
  • flat: one object split into args/options. This is used by MCP-style calls.

Before this PR, only argv went through incur's validation wrapper. The object-based modes called Zod directly:

command.options.parse(inputOptions)
command.args.parse(split.args)
command.options.parse(split.options)

That meant bad structured input like this:

inputOptions: { name: 123 } // schema expects string
parseMode: 'split'

did not produce the same structured field error as CLI input.

Tests failing before fix

src/Cli.test.ts adds direct executor coverage for both object-based modes.

For split and flat, invalid command input now returns:

{
  ok: false,
  error: {
    code: 'VALIDATION_ERROR',
    fieldErrors: [{ code: 'invalid_type', missing: false, path: 'name' }]
  }
}

src/Cli.test.ts also guards the boundary: if user code throws a Zod error inside run(), it is still treated as a handler error, not as command input validation.

run() {
  z.object({ name: z.string() }).parse({ name: 123 })
}

Expected result:

{ ok: false, error: { code: 'UNKNOWN' } }

Fix

Parser.zodParse() is exported so the command executor can reuse the existing Zod-to-ValidationError conversion.

Command.execute() now uses that wrapper for:

  • split options.
  • flat args.
  • flat options.

The change is intentionally narrow: only command input parsing is normalized. Handler-thrown Zod errors still follow the normal handler error path.

@0xpolarzero 0xpolarzero force-pushed the parse-object-validation branch 2 times, most recently from b2f746d to 3fd525c Compare May 22, 2026 13:50
@0xpolarzero 0xpolarzero changed the title fix: normalize object validation errors fix(1): normalize object validation errors May 22, 2026
@0xpolarzero 0xpolarzero changed the title fix(1): normalize object validation errors fix: normalize object validation errors May 24, 2026
@0xpolarzero 0xpolarzero force-pushed the parse-object-validation branch from 3fd525c to 0217d7b Compare May 27, 2026 17:21
@0xpolarzero 0xpolarzero force-pushed the parse-object-validation branch from 0217d7b to 85d238a Compare May 27, 2026 18:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant