DefinitelyTyped/DefinitelyTyped · error · Error

Bad $inc parameter - value must be a number

Error message

Bad $inc parameter - value must be a number

What it means

Thrown by the $inc handler in updateDocument. For each field in update.$inc the sproc runs isNaN(update.$inc[field]); if the value coerces to NaN (non-numeric), it aborts with this message before touching the document. isNaN is applied loosely, so null/undefined/""/"abc"/objects all fail; numeric strings pass (isNaN("5") is false), which is intentional DocumentDB-sample behavior.

Source

Thrown at types/documentdb-server/documentdb-server-tests.ts:521

        );

        // If we hit execution bounds - throw an exception.
        if (!isAccepted) {
            throw new Error("The stored procedure timed out.");
        }
    }

    // Operator implementations.
    // The $inc operator increments the value of a field by a specified amount.
    function inc(document: any, update: any) {
        var fields: string[], i: number;

        if (update.$inc) {
            fields = Object.keys(update.$inc);
            for (i = 0; i < fields.length; i++) {
                if (isNaN(update.$inc[fields[i]])) {
                    // Validate the field; throw an exception if it is not a number (can't increment by NaN).
                    throw new Error("Bad $inc parameter - value must be a number");
                } else if (document[fields[i]]) {
                    // If the field exists, increment it by the given amount.
                    document[fields[i]] += update.$inc[fields[i]];
                } else {
                    // Otherwise set the field to the given amount.
                    document[fields[i]] = update.$inc[fields[i]];
                }
            }
        }
    }

    // The $mul operator multiplies the value of the field by the specified amount.
    function mul(document: any, update: any) {
        var fields: string[], i: number;

        if (update.$mul) {
            fields = Object.keys(update.$mul);
            for (i = 0; i < fields.length; i++) {

View on GitHub (pinned to 8f494947ae)

Solutions

  1. Coerce $inc values to numbers on the client before invoking the sproc: Number(v) and check Number.isFinite.
  2. If consuming MongoDB Extended JSON, unwrap {$numberInt/$numberDouble} to plain numbers first.
  3. Add a unit test that builds the update object with explicit numeric literals.
  4. Validate the whole update spec with a JSON-schema that requires $inc.* to be number.

Example fix

// before
const update = { $inc: { visits: req.body.visits } }; // visits arrives as "5"
client.executeStoredProcedure(updateSprocLink, [id, update], { partitionKey }, cb);

// after: coerce + validate before sending
const visits = Number(req.body.visits);
if (!Number.isFinite(visits)) return next(new TypeError('visits must be numeric'));
const update = { $inc: { visits } };
client.executeStoredProcedure(updateSprocLink, [id, update], { partitionKey }, cb);
Defensive patterns

Strategy: validation

Validate before calling

// Validate the whole update object before invoking the sproc.
function validateInc(update) {
  if (!update || !update.$inc) return true;
  return Object.entries(update.$inc).every(([, v]) => Number.isFinite(Number(v)));
}
if (!validateInc(update)) throw new TypeError('$inc values must be finite numbers');

Type guard

// Type-narrow the $inc operand at the boundary.
interface IncOp { $inc?: Record<string, number>; }
function isIncOp(u: unknown): u is IncOp {
  if (!u || typeof u !== 'object' || !("$inc" in u)) return true;
  const inc = (u as any).$inc;
  return inc == null || Object.values(inc).every((v) => typeof v === 'number' && Number.isFinite(v));
}

Prevention

When it happens

Trigger: Passing an update whose $inc maps a field to a non-numeric value: update = { $inc: { count: "five" } }, { $inc: { count: null } }, { $inc: { count: undefined } }, or { $inc: { count: { $numberInt: 5 } } } (MongoDB Extended JSON forms are not unwrapped here).

Common situations: Serializing updates from a form/API without coercing types; mixing MongoDB driver conventions (e.g., wrapped numeric types) with this Cosmos sproc; passing a value that came back from another query as a string.

Related errors


AI-assisted analysis of DefinitelyTyped/DefinitelyTyped@8f494947ae (2026-08-12). Data as JSON: /api/errors/7114ffa4b2eb5b70. Report an issue: GitHub.