Skip to content

fix: serialize BigInt values in integer anyOf/oneOf and multi-type schemas - #875

Open
marko1olo wants to merge 1 commit into
fastify:mainfrom
marko1olo:fix/bigint-integer-union
Open

fix: serialize BigInt values in integer anyOf/oneOf and multi-type schemas#875
marko1olo wants to merge 1 commit into
fastify:mainfrom
marko1olo:fix/bigint-integer-union

Conversation

@marko1olo

Copy link
Copy Markdown

Problem

When a schema field is typed as anyOf: [{type: 'integer'}, {type: 'null'}] or type: ['integer', 'null'], passing a BigInt value (e.g. 12n) throws an error instead of serializing it as an integer.

const stringify = build({ anyOf: [{ type: 'integer' }, { type: 'null' }] })
stringify(12n)
// Before: TypeError: The value of '#' does not match schema definition.
// After:  "12"

This was reported in #501 where Typebox's Type.Union([Type.Integer(), Type.Null()]) produces exactly this schema shape.

Root cause

Two code paths were affected:

  1. buildMultiTypeSerializer (for type: ['integer', 'null']): the branch condition was Number.isInteger(x) || x === null. Number.isInteger(12n) returns false, so BigInt fell through.

  2. buildOneOf (for anyOf/oneOf): branch selection uses validator.validate() (AJV). AJV does not recognise BigInt as type: 'integer' by default, so BigInt never matched any branch.

Note: lib/serializer.js asInteger() already handles BigInt correctly via .toString().

Fix

  • buildMultiTypeSerializer: add typeof input === 'bigint' to the integer guard.
  • buildOneOf: when an option schema has type: 'integer', prefix the AJV check with typeof input === 'bigint' || so BigInt values are routed to asInteger().

Tests

Added 2 new test cases in test/typesArray.test.js covering both code paths. Full 501-test suite passes.

AJV does not recognise BigInt as type 'integer', so values like 12n were
always falling through to the TypeError branch in anyOf/oneOf union code,
and in multi-type (type array) serializers the Number.isInteger() guard
also rejects BigInt.

Two targeted changes:
- buildMultiTypeSerializer: add 	ypeof input === 'bigint' alongside
  Number.isInteger() in the integer branch condition.
- buildOneOf: when an option schema declares type 'integer', prefix the
  AJV validator.validate() call with a BigInt type-guard so BigInt values
  are correctly routed to asInteger() (which already handles BigInt).

asInteger() in lib/serializer.js already converts BigInt to string via
.toString(), so no change is needed there.

Fixes fastify#501
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