remix-run/react-router · error · Error

package.json ${pkgKey} are invalid

Error message

package.json ${pkgKey} are invalid

What it means

Thrown in updatePackageJSON() while iterating over ['dependencies','devDependencies']: the package.json parsed fine, but one of these fields is present and is not a valid JSON object (isValidJsonObject fails — it's an array, string, number, null, or otherwise non-object). React Router needs to rewrite react-router/@react-router/* versions in these maps, so they must be plain objects.

Source

Thrown at packages/create-react-router/index.ts:695

    error(
      "Oh no!",
      "The provided template must be a React Router project with a `package.json` " +
        `file, but that file is invalid.`,
    );
    throw err;
  }

  for (let pkgKey of ["dependencies", "devDependencies"] as const) {
    let dependencies = packageJSON[pkgKey];
    if (!dependencies) continue;

    if (!isValidJsonObject(dependencies)) {
      error(
        "Oh no!",
        "The provided template must be a React Router project with a `package.json` " +
          `file, but its ${pkgKey} value is invalid.`,
      );
      throw new Error(`package.json ${pkgKey} are invalid`);
    }

    for (let dependency in dependencies) {
      let version = dependencies[dependency];
      if (
        (dependency.startsWith("@react-router/") ||
          dependency === "react-router") &&
        version === "*"
      ) {
        dependencies[dependency] = semver.prerelease(ctx.reactRouterVersion)
          ? // Templates created from prereleases should pin to a specific version
            ctx.reactRouterVersion
          : "^" + ctx.reactRouterVersion;
      }
    }
  }

  packageJSON.name = ctx.projectName;

View on GitHub (pinned to 1fd704a7da)

Solutions

  1. Open the template's package.json and ensure dependencies and devDependencies are both plain objects like { "react": "^18.0.0" }.
  2. Remove the field entirely if it should be empty (an absent field is skipped via the `if (!dependencies) continue` guard).
  3. Validate the JSON with npm/your editor and fix the malformed value.
  4. After fixing, re-run create-react-router.

Example fix

// before (template package.json)
{
  "name": "bad-template",
  "dependencies": ["react", "react-dom"]
}
// after
{
  "name": "bad-template",
  "dependencies": { "react": "^18.0.0", "react-dom": "^18.0.0" }
}
Defensive patterns

Strategy: validation

Validate before calling

function isValidDepsMap(v: unknown): boolean {
  return v == null || (typeof v === 'object' && !Array.isArray(v));
}
// Validate the template's package.json shape before scaffolding
const pkg = JSON.parse(fs.readFileSync(path.join(templateDir, 'package.json'), 'utf-8'));
if (!isValidDepsMap(pkg.dependencies) || !isValidDepsMap(pkg.devDependencies)) {
  throw new Error('dependencies/devDependencies must be objects or absent');
}

Type guard

function isValidJsonObject(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

Prevention

When it happens

Trigger: A template whose package.json has "dependencies": "./libs" (string), "dependencies": ["react"] (array), or "devDependencies": null. Any non-object JSON value for either field triggers the throw.

Common situations: Hand-edited package.json with a typo; a template generated by tooling that wrote dependencies as a list; a JSON merge that produced a non-object value; copy-pasting from a docs example that used a non-standard format.

Related errors


AI-assisted analysis of remix-run/react-router@1fd704a7da (2026-08-12). Data as JSON: /api/errors/44e4f8383cbd68b6. Report an issue: GitHub.