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. ResolutionView on GitHub (pinned to 06b6eae39d)
Solutions
- Restore package.json to a proper JSON object with name/version and dependencies.
- Run npm init to regenerate a valid package.json skeleton.
- 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
- Keep package.json root as a JSON object.
- Validate typeof parsed === 'object' after JSON.parse in CI.
- Avoid tooling that writes scalar values into package.json.
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
- ${filepath}: No config detected
- .babel property must be an object
- No config detected
- Config returned typeof ${typeof options}
- Expected config object but found array
AI-assisted analysis of babel/babel@06b6eae39d (2026-08-03).
Data as JSON: /data/errors/d680cd4be150853a.json.
Report an issue: GitHub.