{"record":{"id":"5034277a8f14fcb4","repo":"paperclipai/paperclip","slug":"acpx-package-packagename-has-invalid-package-me","errorCode":null,"errorMessage":"ACPX package ${packageName} has invalid package metadata","messagePattern":"ACPX package (.+?) has invalid package metadata","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/acpx/installation-integrity.ts","lineNumber":825,"sourceCode":"}\n\nasync function readPackageJson(\n  packageJsonPath: string,\n  packageName: string,\n): Promise<AcpxPackageMetadata> {\n  const bytes = await readBoundedRegularFile(\n    packageJsonPath,\n    MAX_PACKAGE_JSON_BYTES,\n    `${packageName} package.json`,\n  );\n  let value: unknown;\n  try {\n    value = JSON.parse(bytes.toString(\"utf8\"));\n  } catch {\n    throw new Error(`ACPX package ${packageName} has malformed package.json`);\n  }\n  if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n    throw new Error(`ACPX package ${packageName} has invalid package metadata`);\n  }\n  return value as AcpxPackageMetadata;\n}\n\nasync function verifyQualifiedRuntimeExecutable(input: {\n  profile: QualifiedAcpxProfile;\n  runtimePackage: AcpxPackageMetadata;\n  runtimePackageJsonPath: string;\n  resolvePackageJson: AcpxPackageJsonResolver;\n}): Promise<VerifiedAcpxRuntimeExecutable | null> {\n  const qualification =\n    input.profile.agent === \"claude\"\n      ? process.platform === \"darwin\" && (process.arch === \"arm64\" || process.arch === \"x64\")\n        ? QUALIFIED_CLAUDE_DARWIN_RUNTIMES[process.arch]\n        : QUALIFIED_CLAUDE_LINUX_X64_RUNTIME\n      : input.profile.agent === \"codex\"\n        ? QUALIFIED_CODEX_LINUX_X64_RUNTIME\n        : null;","sourceCodeStart":807,"sourceCodeEnd":843,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/acpx/installation-integrity.ts#L807-L843","documentation":"readPackageJson parses a package.json for an ACPX package and requires the result to be a plain object. The JSON parsed successfully but is not of the expected shape — an array, string, number, or null — so the metadata cannot be used as AcpxPackageMetadata. This guards the downstream version/dependency checks against malformed metadata.","triggerScenarios":"readPackageJson (called via serverPackage, dependencyPackage, executablePackage, or verifyQualifiedAcpxInstallation) reads a package.json whose top-level JSON value is valid JSON but not a non-null, non-array object.","commonSituations":"A package.json replaced by a lockfile-style array, an error page, or a build artifact; hand-edited file wrapping the object in an array; a placeholder file (e.g. `[]` or `\"\"`) left by a failed install; resolving the wrong file path that happens to contain valid non-object JSON.","solutions":["Inspect the package.json at the resolved path and restore a valid top-level JSON object with name/version fields.","Reinstall the affected package so a correct package.json is written by the package manager.","Verify resolvePackageJson/realpath pointed at the intended package's package.json, not an unrelated JSON file.","If the file is generated, fix the generator so it always emits a single JSON object at top level."],"exampleFix":"// before (package.json)\n[]\n// after\n{ \"name\": \"@anthropic-ai/claude-code\", \"version\": \"2.0.14\" }","handlingStrategy":"type-guard","validationCode":"const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, \"utf8\"));\nif (typeof pkg !== \"object\" || pkg === null || Array.isArray(pkg)) {\n  throw new Error(`${pkgJsonPath} is not a package.json object; reinstall the package`);\n}","typeGuard":"function isPackageMetadata(v) {\n  return typeof v === \"object\" && v !== null && !Array.isArray(v) && typeof v.name === \"string\";\n}","tryCatchPattern":"try {\n  await verifyQualifiedAcpxInstallation(input);\n} catch (e) {\n  if (e.message.includes(\"has invalid package metadata\")) {\n    await reinstallAffectedPackage();\n    await verifyQualifiedAcpxInstallation(input);\n  } else throw e;\n}","preventionTips":["Never hand-edit package.json files in the install tree; let the package manager own them.","Validate top-level package.json shape (object with name/version) in install post-checks.","Confirm resolver paths point at real package directories, not stray JSON files."],"tags":["installation-integrity","acpx","package-json","json-validation"],"backgroundTag":"unexpected-response-shape","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}