zloirock/core-js · error · SyntaxError

Failed to parse number at: ${i}

Error message

Failed to parse number at: ${i}

What it means

This SyntaxError is thrown by core-js's polyfilled JSON.parse while parsing a JSON number token. It fires when, at the current parse position, the source does not begin with a valid JSON number: there is no optional '-', no '0', and no non-zero digit to start an integer. The library throws it because the text at that offset cannot possibly be a JSON number, so parsing must abort per the JSON grammar.

Source

Thrown at packages/core-js/modules/es.json.parse.js:207

        break;
      }
    }
    if (!closed) throw new SyntaxError('Unterminated array at: ' + i);
    return this.node(OBJECT, array, this.index, i, nodes);
  },
  string: function () {
    var index = this.index;
    var parsed = parseJSONString(this.source, this.index + 1);
    return this.node(PRIMITIVE, parsed.value, index, parsed.end);
  },
  number: function () {
    var source = this.source;
    var startIndex = this.index;
    var i = startIndex;
    if (at(source, i) === '-') i++;
    if (at(source, i) === '0') i++;
    else if (exec(IS_NON_ZERO_DIGIT, at(source, i))) i = this.skip(IS_DIGIT, i + 1);
    else throw new SyntaxError('Failed to parse number at: ' + i);
    if (at(source, i) === '.') {
      var fractionStartIndex = i + 1;
      i = this.skip(IS_DIGIT, fractionStartIndex);
      if (fractionStartIndex === i) throw new SyntaxError("Failed to parse number's fraction at: " + i);
    }
    if (at(source, i) === 'e' || at(source, i) === 'E') {
      i++;
      if (at(source, i) === '+' || at(source, i) === '-') i++;
      var exponentStartIndex = i;
      i = this.skip(IS_DIGIT, i);
      if (exponentStartIndex === i) throw new SyntaxError("Failed to parse number's exponent value at: " + i);
    }
    return this.node(PRIMITIVE, Number(slice(source, startIndex, i)), startIndex, i);
  },
  keyword: function (value) {
    var keyword = '' + value;
    var index = this.index;
    var endIndex = index + keyword.length;

View on GitHub (pinned to 84e45fba09)

Solutions

  1. Validate/repair the JSON text before parsing (e.g. with a linter or a JSON schema/parser check) and ensure every number starts with a digit or '-' followed by a digit
  2. Use JSON5 or a tolerant parser if you legitimately need '.5' or '+1' style numbers instead of forcing them through JSON.parse
  3. If data comes from an external system, log the string and the index reported in the message to inspect the offending character
  4. Ensure core-js is not shadowing a working native JSON.parse unnecessarily (check useBuiltPure/exports configuration); on modern engines native JSON.parse gives a clearer message
  5. Wrap JSON.parse in try/catch and surface a user-friendly error including the failing index

Example fix

// before
JSON.parse('{"score": .5}'); // SyntaxError: Failed to parse number at: 10
// after
JSON.parse('{"score": 0.5}');
Defensive patterns

Strategy: validation

Validate before calling

function looksLikeJsonNumberAt(str, i) {
  return /^-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)?/.test(str.slice(i));
}
// before parsing: ensure every value position starts with a valid token
if (!looksLikeJsonNumberAt(input, idx)) throw new Error('Invalid number at ' + idx);

Type guard

function isValidJsonNumber(s) {
  return typeof s === 'string' && /^-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)?$/.test(s.trim());
}

Try / catch

try {
  return JSON.parse(input);
} catch (e) {
  if (e instanceof SyntaxError && /Failed to parse number/.test(e.message)) {
    throw new Error('Malformed number in JSON payload: ' + e.message);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling JSON.parse (routed through the core-js es.json.parse polyfill, e.g. on engines without native JSON or with the pure version) on text where a value position starts with a character that cannot begin a number, such as '+5', '.5', '01x' contexts, or a stray digit-adjacent symbol after '-' like '-.' or '- '.

Common situations: Parsing hand-edited config or data files where numbers were written as '.5' or '+1'; receiving truncated or corrupted JSON over the wire; building JSON strings via naive string concatenation (e.g. 'value=' + x producing invalid tokens); running on old engines where core-js replaces native JSON.parse so even slightly malformed JSON hits polyfill-specific messages.

Understand the failure class

Related errors


AI-assisted analysis of zloirock/core-js@84e45fba09 (2026-08-30). Data as JSON: /api/errors/7c34e889648521d4. Report an issue: GitHub.