Skip to content

Spec / interop: runtime guarantees for FailureResult.issues (Array subclasses, JSON.stringify) #166

@gabroberge

Description

@gabroberge

Context

While integrating Standard Schema into a generic consumer (NestJS 12 StandardSchemaValidationPipe + @Body({ schema: … }) with ArkType), validation failures surfaced as HTTP 500 errors during response serialization instead of a stable 4xx JSON response.

The root cause was not an Express/Nest HTTP bug directly, but rather how FailureResult.issues interacted with common generic framework code.

In practice:

  1. issues is frequently treated as “array-like” by consumers:

    • e.g. issues.map(issue => issue.message)
  2. Some implementations expose issues as an Array subclass without @@species = Array.

  3. In those cases, calling array methods like map() may allocate another instance of that subclass whose indexed values contain primitive callback results (e.g. strings) rather than Issue objects.

  4. Later, JSON.stringify() may invoke a custom toJSON() implementation on that derived array-like value, which assumes every indexed slot exposes toJSON().

Result:

  • TypeError: e.toJSON is not a function

Related context

ArkType-side fix / discussion:

Addresses one concrete implementation; the following is a proposal for how Standard Schema itself could document runtime/interop expectations for FailureResult.issues so the ecosystem does not rely on ad‑hoc knowledge per library.

Related consumer report (NestJS v12 draft):

This issue is not asking NestJS (or any single framework) to special-case ArkType—the goal is to clarify what Standard Schema should promise at the validation/serialization boundary. The ArkType PR is an implementation-side fix; this thread is about whether the spec or official guidance should reduce the same class of footguns across validators and consumers.


Relation to existing issues

This issue is a different symptom, but points to the same broader concern:

generic consumers cannot safely assume issues behaves like a plain JSON-serializable Array<Issue> without implementation-specific knowledge.


Discussion / proposal

Would it make sense for Standard Schema to clarify expectations around FailureResult.issues, either normatively or through implementation guidance?

For example:

  • Should issues be expected to work safely with:

    • common array operations
    • generic framework serialization
    • JSON.stringify
    • “plain array” consumer assumptions
  • Or alternatively, should the spec explicitly document that:

    • issues may be richer than plain Issue[]
    • array semantics may differ across implementations
    • consumers should defensively normalize values before serialization

Potential implementation guidance could include:

  • setting @@species = Array when subclassing Array
  • avoiding assumptions in custom toJSON
  • documenting serialization characteristics explicitly

The goal is not to require frameworks to special-case each validator library, but rather to reduce interoperability footguns at the Standard Schema boundary as ecosystem adoption grows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions