Automattic/mongoose · error · CastError

Cast to BigInt failed for value "${value}" (type ${valueType

Error message

Cast to BigInt failed for value "${value}" (type ${valueType}) at path "${path}"

What it means

SchemaBigInt.cast delegates to the path's custom caster (_castFunction) or SchemaBigInt.cast(), which runs the value through BigInt(); anything BigInt() rejects (fractional numbers, non-numeric strings, symbols) is rethrown as CastError BigInt naming the path.

Source

Thrown at lib/schema/bigint.js:173

 * @param {object} value
 * @param {object} model this value is optional
 * @api private
 */

SchemaBigInt.prototype.cast = function(value) {
  let castBigInt;
  if (typeof this._castFunction === 'function') {
    castBigInt = this._castFunction;
  } else if (typeof this.constructor.cast === 'function') {
    castBigInt = this.constructor.cast();
  } else {
    castBigInt = SchemaBigInt.cast();
  }

  try {
    return castBigInt(value);
  } catch (error) {
    throw new CastError('BigInt', value, this.path, error, this);
  }
};

/*!
 * ignore
 */

const $conditionalHandlers = {
  ...SchemaType.prototype.$conditionalHandlers,
  $gt: handleSingle,
  $gte: handleSingle,
  $lt: handleSingle,
  $lte: handleSingle
};

/**
 * Contains the handlers for different query operators for this schema type.
 * For example, `$conditionalHandlers.$in` is the function Mongoose calls to cast `$in` filter operators.

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Validate and convert explicitly: require integer-compatible input, then assign BigInt(value); use 1n literals in code.
  2. Reject decimal strings with /^-?\d+$/ before assignment, or round intentionally then convert.
  3. Install a lenient global caster if decimals must be accepted: mongoose.Schema.Types.BigInt.cast(v => BigInt(Math.round(Number(v)))).

Example fix

// before
doc.amount = req.body.amount; // '19.99' -> CastError BigInt

// after
const raw = String(req.body.amount);
if (!/^-?\d+$/.test(raw)) throw new Error('amount must be an integer string');
doc.amount = BigInt(raw);
Defensive patterns

Strategy: validation

Validate before calling

const toBigInt = (v) => {
  if (typeof v === 'bigint') return v;
  const s = typeof v === 'string' || typeof v === 'number' ? String(v) : null;
  if (s == null || !/^-?\d+$/.test(s)) throw new TypeError(`not bigint-safe: ${String(v)}`);
  return BigInt(s);
};
doc.amount = toBigInt(req.body.amount);

Type guard

const isBigIntLike = (v) => typeof v === 'bigint' || ((typeof v === 'string' || (typeof v === 'number' && Number.isInteger(v))) && /^-?\d+$/.test(String(v)));

Try / catch

try {
  doc.big = value;
} catch (err) {
  if (err instanceof mongoose.Error.CastError && err.kind === 'BigInt') {
    doc.big = toBigInt(value); // or reject the request
  } else throw err;
}

Prevention

When it happens

Trigger: `doc.big = 1.5` or `'1.5'`; `doc.big = '12px'`; JSON-parsed fractional numbers assigned to a BigInt path; float arithmetic results that already lost integer precision.

Common situations: JSON APIs (JSON cannot carry BigInt natively, and decimals arrive as Number); monetary values computed as floats then assigned to BigInt paths; string inputs never regex-checked for integer form.

Related errors


AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21). Data as JSON: /api/errors/330675c03113bdb1. Report an issue: GitHub.