babel/babel · error · ConfigError

Config returned typeof ${typeof options}

Error message

Config returned typeof ${typeof options}

What it means

readConfigPackage parses a package.json and then verifies the result is an object. If JSON.parse succeeds but yields a non-object primitive (string, number, boolean), Babel throws ConfigError 'Config returned typeof ${typeof options}'. A package.json root must be a JSON object; a scalar value is invalid package metadata.

Source

Thrown at packages/babel-core/src/config/files/package.ts:26

const PACKAGE_FILENAME = "package.json";

const readConfigPackage = makeStaticFileCache(
  (filepath, content): ConfigFile => {
    let options;
    try {
      options = JSON.parse(content) as unknown;
    } catch (err) {
      throw new ConfigError(
        `Error while parsing JSON - ${err.message}`,
        filepath,
      );
    }

    if (!options) throw new Error(`${filepath}: No config detected`);

    if (typeof options !== "object") {
      throw new ConfigError(
        `Config returned typeof ${typeof options}`,
        filepath,
      );
    }
    if (Array.isArray(options)) {
      throw new ConfigError(`Expected config object but found array`, filepath);
    }

    return {
      filepath,
      dirname: path.dirname(filepath),
      options,
    };
  },
);

/**
 * Find metadata about the package that this file is inside of. Resolution

View on GitHub (pinned to 06b6eae39d)

Solutions

  1. Restore package.json to a proper JSON object with name/version and dependencies.
  2. Run npm init to regenerate a valid package.json skeleton.
  3. Add a pre-build validation that asserts typeof require('./package.json') === 'object'.

Example fix

// before - package.json throws error 39
"my-package"

// after
{
  "name": "my-package",
  "version": "1.0.0"
}
Defensive patterns

Strategy: type-guard

Validate before calling

const fs = require('fs');
function checkPackageType(dir) {
  const file = require('path').join(dir, 'package.json');
  if (!fs.existsSync(file)) return;
  const parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
  if (typeof parsed !== 'object' || parsed === null) {
    throw new Error(`${file}: package.json must be an object, got ${typeof parsed}`);
  }
}

Type guard

function isPackageObject(value: unknown): value is { name?: string; version?: string; [k: string]: unknown } {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

Try / catch

try { babel.transformFileSync(file); }
catch (err) {
  if (/Config returned typeof/.test(err.message) && /package\.json/.test(err.filename || '')) {
    console.error('package.json root must be an object');
  }
  throw err;
}

Prevention

When it happens

Trigger: A package.json whose entire content is a quoted string ("my-package"), a number (42), or a boolean (true). These are valid JSON primitives but not valid package manifests.

Common situations: Accidentally overwriting package.json with a scalar (e.g. writing only the package name); tooling that writes a single value; misgenerated file.

Related errors


AI-assisted analysis of babel/babel@06b6eae39d (2026-08-03). Data as JSON: /data/errors/d680cd4be150853a.json. Report an issue: GitHub.