Skip to content

fix: normalize object validation errors#3

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

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

Conversation

@0xpolarzero
Copy link
Copy Markdown
Owner

@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 changed the title fix(1): normalize object validation errors fix: normalize object validation errors May 24, 2026
Copy link
Copy Markdown
Owner Author

0xpolarzero commented May 25, 2026

@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