{"record":{"id":"43810274a12844d1","repo":"paperclipai/paperclip","slug":"could-not-read-managed-install-manifest-at-paths","errorCode":null,"errorMessage":"Could not read managed install manifest at ${paths.manifestPath}: ${String(error)}","messagePattern":"Could not read managed install manifest at (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/install-store.ts","lineNumber":229,"sourceCode":"  }\n  return path.join(paths.installsRoot, source, identifier);\n}\n\nexport function readInstallManifest(paths = resolveInstallStorePaths()): InstallManifest | null {\n  try {\n    const value = JSON.parse(fs.readFileSync(paths.manifestPath, \"utf8\")) as InstallManifest;\n    if (\n      value.schemaVersion !== INSTALL_MANIFEST_VERSION ||\n      (value.source !== \"npm\" && value.source !== \"git\") ||\n      !Array.isArray(value.previous) ||\n      typeof value.payloadPath !== \"string\"\n    ) {\n      throw new Error(\"unsupported manifest shape\");\n    }\n    return value;\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n    throw new Error(`Could not read managed install manifest at ${paths.manifestPath}: ${String(error)}`);\n  }\n}\n\nexport function writeInstallManifestAtomic(\n  manifest: InstallManifest,\n  paths = resolveInstallStorePaths(),\n): void {\n  ensurePrivateDirectory(paths.cliRoot);\n  const temporaryPath = `${paths.manifestPath}.tmp-${process.pid}-${Date.now()}`;\n  try {\n    fs.writeFileSync(temporaryPath, `${JSON.stringify(manifest, null, 2)}\\n`, { mode: 0o600 });\n    fs.renameSync(temporaryPath, paths.manifestPath);\n  } finally {\n    fs.rmSync(temporaryPath, { force: true });\n  }\n}\n\nfunction assertPayloadPath(payloadPath: string, paths: InstallStorePaths): void {","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/install-store.ts#L211-L247","documentation":"Thrown by readInstallManifest()'s outer catch block for any error other than ENOENT while reading or validating install.json. This wraps the underlying error (which may be the 'unsupported manifest shape' error from the shape check, a JSON.parse SyntaxError, or a filesystem permission error) into a single message that includes the manifest path and the original error's string representation. This is the error callers actually see when the manifest is corrupt.","triggerScenarios":"Called readInstallManifest() where reading install.json throws a non-ENOENT error: JSON.parse fails (malformed JSON), or the inner shape-validation throws 'unsupported manifest shape', or readFileSync fails with EACCES/EIO, etc. The catch re-throws with this wrapper.","commonSituations":"1) install.json is truncated or contains invalid JSON (partial write, editor save race). 2) The manifest shape is wrong (see error 276 — the inner throw becomes the 'String(error)' portion of this message). 3) Permissions deny reading the file. 4) Disk I/O error mid-read.","solutions":["Read the embedded inner error in the message: if it says 'unsupported manifest shape', apply error 276's fixes; if it is a SyntaxError, the JSON is malformed.","Open ~/.paperclip/cli/install.json and either repair the JSON syntax or replace the file with a known-good manifest.","If unrecoverable, remove cliRoot and reinitialize: 'rm -rf ~/.paperclip/cli && paperclipai install'.","If the inner error is EACCES, fix permissions on install.json (chown/chmod) to be readable by the current user."],"exampleFix":"// before: install.json is truncated JSON\n$ cat ~/.paperclip/cli/install.json\n{ \"schemaVersion\": 1, \"source\": \"np\n\n// after\n$ rm -rf ~/.paperclip/cli\n$ paperclipai install","handlingStrategy":"try-catch","validationCode":"import fs from \"node:fs\";\nimport { resolveInstallStorePaths } from \"./install-store.js\";\n\nfunction manifestIsReadable(paths = resolveInstallStorePaths()): boolean {\n  if (!fs.existsSync(paths.manifestPath)) return false;\n  try { JSON.parse(fs.readFileSync(paths.manifestPath, \"utf8\")); return true; }\n  catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"import { readInstallManifest } from \"./install-store.js\";\n\nlet manifest;\ntry {\n  manifest = readInstallManifest(paths);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"Could not read managed install manifest\")) {\n    console.error(\"Manifest corrupt:\", err.message);\n    // prompt user; on approval reset store\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["Treat install.json as binary — do not edit it with text tools that may corrupt it.","Ensure the install write completes (atomic rename) before reading the manifest.","Fix permissions (chmod/chown) on install.json if access errors appear.","Restore from backup or reinitialize if the JSON is malformed."],"tags":["install-store","manifest","json","cli"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}