parcel-bundler/parcel · error · ThrowableDiagnostic

Expected package.json contents to be an object.

Error message

Expected package.json contents to be an object.

What it means

Thrown by getConflictingLocalDependencies() in utils.js when package.json parses as valid JSON but the result is not an object — it could be an array, string, number, boolean, or null. The check is `typeof pkg !== 'object' || pkg == null`, which catches arrays (typeof 'object' but not a plain object), null (typeof 'object'), strings, numbers, and booleans. This fires AFTER JSON.parse succeeds, so the JSON is syntactically valid but semantically wrong for a package.json.

Source

Thrown at packages/core/package-manager/src/utils.js:67

  }

  let pkgStr = await fs.readFile(pkgPath, 'utf8');
  let pkg;
  try {
    pkg = JSON.parse(pkgStr);
  } catch (e) {
    // TODO: codeframe
    throw new ThrowableDiagnostic({
      diagnostic: {
        message: 'Failed to parse package.json',
        origin: '@parcel/package-manager',
      },
    });
  }

  if (typeof pkg !== 'object' || pkg == null) {
    // TODO: codeframe
    throw new ThrowableDiagnostic({
      diagnostic: {
        message: 'Expected package.json contents to be an object.',
        origin: '@parcel/package-manager',
      },
    });
  }

  let fields = [];
  for (let field of ['dependencies', 'devDependencies', 'peerDependencies']) {
    if (
      typeof pkg[field] === 'object' &&
      pkg[field] != null &&
      pkg[field][name] != null
    ) {
      fields.push(field);
    }
  }

View on GitHub (pinned to 59484858a1)

Solutions

  1. Open package.json and ensure it contains a JSON object literal `{ ... }` at the top level.
  2. If the file is empty, replace it with a minimal valid object: `{}`.
  3. Check if a tool or script is generating malformed package.json content.
  4. Validate with: `node -e "const p=require('./package.json'); if(typeof p!=='object'||p===null||Array.isArray(p)) throw new Error('not an object')"`.

Example fix

// before: package.json contains
[]

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

Strategy: validation

Validate before calling

// Validate package.json is an object before use
const fs = require('fs');

function validatePackageJsonObject(filePath) {
  let pkg = JSON.parse(fs.readFileSync(filePath, 'utf8'));
  if (typeof pkg !== 'object' || pkg === null || Array.isArray(pkg)) {
    throw new Error(`Expected ${filePath} to contain a JSON object, got ${Array.isArray(pkg) ? 'array' : typeof pkg}`);
  }
  return pkg;
}

Type guard

// Type guard for parsed package.json
function isValidPackageJson(pkg) {
  return typeof pkg === 'object' &&
    pkg !== null &&
    !Array.isArray(pkg);
}

Try / catch

try {
  await packageManager.resolve(id, from);
} catch (e) {
  if (e.diagnostics?.[0]?.message?.includes('Expected package.json contents to be an object')) {
    // Fix the package.json to be an object literal
    console.error('package.json must be a JSON object, not an array or primitive');
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: A package.json file containing valid JSON that is not an object literal — for example `[]` (array), `"some-string"`, `42`, `true`, or `null`. JSON.parse succeeds on these, but the typeof/null check catches them. The subsequent code that iterates ['dependencies', 'devDependencies', 'peerDependencies'] fields would fail without this guard.

Common situations: An empty package.json containing just `[]` or `null` (sometimes created by accident). A package.json that was overwritten with a JSON array (e.g., a config file accidentally saved as package.json). A build tool that generates package.json content as a non-object structure.

Related errors


AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13). Data as JSON: /api/errors/7d4c97ded7928b31. Report an issue: GitHub.