axios/axios · warning · AxiosError

ERR_BAD_OPTION

ERR_BAD_OPTION

Error message

Unknown option ' + opt

What it means

Thrown by assertOptions() when an option key is absent from the schema AND allowUnknown !== true. Axios.js calls assertOptions(transitional, schema, false) — allowUnknown is false for transitional — so any unrecognized transitional key throws ERR_BAD_OPTION. By contrast, paramsSerializer and the spelling check pass allowUnknown=true, so unknowns are permitted there. This catches typos and retired-but-not-removed keys in the transitional object.

Source

Thrown at lib/helpers/validator.js:104

  let i = keys.length;
  while (i-- > 0) {
    const opt = keys[i];
    // Use hasOwnProperty so a polluted Object.prototype.<opt> cannot supply
    // a non-function validator and cause a TypeError.
    const validator = Object.prototype.hasOwnProperty.call(schema, opt) ? schema[opt] : undefined;
    if (validator) {
      const value = options[opt];
      const result = value === undefined || validator(value, opt, options);
      if (result !== true) {
        throw new AxiosError(
          'option ' + opt + ' must be ' + result,
          AxiosError.ERR_BAD_OPTION_VALUE
        );
      }
      continue;
    }
    if (allowUnknown !== true) {
      throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION);
    }
  }
}

export default {
  assertOptions,
  validators,
};

View on GitHub (pinned to e0a02dd166)

Solutions

  1. Remove the unknown key, or correct its spelling to match the documented transitional schema.
  2. Compare your transitional keys against the allowed set for the current axios version.
  3. Move the setting to its correct location — some options belong at the top-level config, not under transitional.

Example fix

// before
axios.get('/url', { transitional: { jsonParsing: true } });

// after
axios.get('/url', { transitional: { silentJSONParsing: true } });
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED_TRANSITIONAL = new Set(['silentJSONParsing','forcedJSONParsing','clarifyTimeoutError','legacyInterceptorReqResOrdering','advertiseZstdAcceptEncoding','validateStatusUndefinedResolves']);
const t = config.transitional || {};
Object.keys(t).forEach(k => { if (!ALLOWED_TRANSITIONAL.has(k)) delete t[k]; });

Type guard

const ALLOWED_TRANSITIONAL = new Set(['silentJSONParsing','forcedJSONParsing','clarifyTimeoutError','legacyInterceptorReqResOrdering','advertiseZstdAcceptEncoding','validateStatusUndefinedResolves']);
const isKnownTransitional = (o) => Object.keys(o || {}).every(k => ALLOWED_TRANSITIONAL.has(k));

Prevention

When it happens

Trigger: axios.get('/url', { transitional: { jsonParsing: true } }) (typo; should be silentJSONParsing); { transitional: { enforceSSL: true } } (nonexistent). Any key not among silentJSONParsing, forcedJSONParsing, clarifyTimeoutError, legacyInterceptorReqResOrdering, advertiseZstdAcceptEncoding, validateStatusUndefinedResolves triggers the throw.

Common situations: Typos in transitional option names; carrying options from old axios versions that were removed without a transitional false marker; IDE autocomplete mistakes; config shared across axios versions where keys were renamed.

Related errors


AI-assisted analysis of axios/axios@e0a02dd166 (2026-08-11). Data as JSON: /api/errors/08e124992e1dd411. Report an issue: GitHub.