Conversation
The union resolver collected each branch's ValidationError into `messages` and then threw without ever reading it, so a failing discriminated union reported every branch's full signature but never the offending property. Only branches that failed at a deeper path are reported: a branch that failed at the union's own path merely restates the mismatch the top-level message already carries, so primitive unions keep their current message. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Nice change - the messages array being write-only is exactly the kind of We run a lot of discriminated unions in our own schemas (116 |
|
Thanks for splitting the unrelated CI fixes into #79! That helps keep this PR focused. |
|
Thanks - keeping it separate was deliberate, since the broken |
Problem
The
unionresolver collects each branch'sValidationErrorintomessages, then throws without ever reading it:schemastery/packages/core/src/index.ts
Lines 704 to 714 in cf0b7e5
messagesis write-only. Linters do not flag it becausepushcounts as a use.For a discriminated union this discards exactly the information the caller needs. Given:
Before — every branch's full signature, but not the one thing that is wrong:
After:
Both detail lines were already computed one line earlier and thrown away.
Why only branches that failed deeper
A branch that failed at the union's own path only restates the mismatch the top-level line already reports, so reporting it is pure noise. A branch that failed at a deeper path names the offending property, which the caller cannot recover otherwise.
Filtering on path depth keeps the change free for the cases that gain nothing:
Absolute paths are preserved through nesting, so the detail stays actionable inside objects and arrays:
Duplicate messages are collapsed.
Scope
Only the message of an already-thrown error changes. Successful validation, the set of inputs that throw, and the error type are all untouched.
Tests
Added
error detailtopackages/core/tests/union.spec.tscovering the surfaced property errors, absolute paths under nesting, and the unchanged primitive-union message.yarn yakumo test coregoes from 45 to 46 passing with no new failures.Note on CI
mainis currently red independently of this change, so a red check here is expected:packages/core/tests/i18n.spec.tsfails onmain(it outlived cf0b7e5 "refa: remove i18n dependency").testscript passes-r esbuild-register, which currentyakumorejects withunknown option: "r".I left both alone to keep this PR to one concern, but happy to fix either here or separately if useful.