{"record":{"id":"ef7a1f668547f0cd","repo":"EveryInc/compound-engineering-plugin","slug":"dropping-unsafe-pi-install-manifest-entry-in-man","errorCode":null,"errorMessage":"Dropping unsafe Pi install-manifest entry in ${manifestPath} (group \"${group}\"): ${JSON.stringify(entry)}","messagePattern":"Dropping unsafe Pi install-manifest entry in (.+?) \\(group \"(.+?)\"\\): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/targets/pi.ts","lineNumber":372,"sourceCode":"    if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n      console.warn(`Ignoring unreadable Pi install manifest at ${manifestPath}.`)\n    }\n  }\n  return null\n}\n\nfunction filterSafePiManifestEntries(\n  entries: unknown[],\n  rootDir: string,\n  manifestPath: string,\n  group: string,\n): string[] {\n  const safe: string[] = []\n  for (const entry of entries) {\n    if (isSafeManagedPath(rootDir, entry)) {\n      safe.push(entry)\n    } else {\n      console.warn(\n        `Dropping unsafe Pi install-manifest entry in ${manifestPath} (group \"${group}\"): ${JSON.stringify(entry)}`,\n      )\n    }\n  }\n  return safe\n}\n\nasync function writeInstallManifest(managedDir: string, manifest: PiInstallManifest): Promise<void> {\n  await writeJson(path.join(managedDir, PI_INSTALL_MANIFEST), manifest)\n}\n\nasync function cleanupRemovedSkills(\n  skillsDir: string,\n  manifest: PiInstallManifest | null,\n  currentSkills: string[],\n): Promise<void> {\n  if (!manifest) return\n  const current = new Set(currentSkills)","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/EveryInc/compound-engineering-plugin/blob/c9c10f8c75412c7232cb2bd663e5fd1cea98d84e/src/targets/pi.ts#L354-L390","documentation":"filterSafePiManifestEntries in src/targets/pi.ts sanitizes entries loaded from a Pi install manifest before any cleanup acts on them. Each entry is checked with isSafeManagedPath(rootDir, entry); unsafe entries (e.g. containing path traversal, absolute paths, or resolving outside the managed root) are dropped from the returned list so cleanup will never delete outside the managed tree. The dropped entry is logged with this warning, including the manifest file, group, and raw entry JSON.","triggerScenarios":"readInstallManifest loads a manifest whose arrays (per group) contain an entry failing isSafeManagedPath — typically entries like '../evil', absolute paths, or entries that via symlinks would resolve outside rootDir. This can happen when the manifest was hand-edited or written by an older/buggy version.","commonSituations":"Manually editing the Pi install manifest to add paths; a previous tool version recording paths in a different format; corrupted or tampered manifest files; copying a manifest between machines with different layouts.","solutions":["Inspect the named manifestPath and group; remove or correct the offending entry so it is a safe relative path inside the managed root.","If the manifest was hand-edited, revert to a freshly generated manifest by re-running the install (after backing up).","If the entries are legitimate but flagged (e.g. you intentionally moved content), reinstall so the manifest regenerates with conforming relative entries.","Note the dropped entry means that path will NOT be cleaned up; delete it manually if it is stale."],"exampleFix":"// before: manifest entry that fails the safety check\n\"skills\": [\"ce-plan\", \"../../.ssh\"]\n// after: only safe relative entries\n\"skills\": [\"ce-plan\"]","handlingStrategy":"validation","validationCode":"function isSafeManagedEntry(rootDir: string, entry: string): boolean {\n  if (typeof entry !== 'string' || entry.length === 0) return false\n  if (path.isAbsolute(entry)) return false\n  const resolved = path.resolve(rootDir, entry)\n  return resolved.startsWith(path.resolve(rootDir) + path.sep)\n}\n// audit manifest entries before install: entries.every(e => isSafeManagedEntry(rootDir, e))","typeGuard":"function isSafeEntry(entry: unknown): entry is string {\n  return typeof entry === 'string' && entry.length > 0 &&\n    !path.isAbsolute(entry) && !entry.split(/[\\\\/]/).includes('..')\n}","tryCatchPattern":null,"preventionTips":["Never hand-edit install manifests; regenerate them by reinstalling","Validate manifest JSON after any tool or script that rewrites it","Treat dropped-entry warnings as a signal the manifest is stale or tampered — back up and reinstall"],"tags":["pi","manifest","path-safety","validation"],"backgroundTag":"unsafe-manifest-entry-dropped","analyzedSha":"c9c10f8c75412c7232cb2bd663e5fd1cea98d84e","analyzedAt":"2026-08-31T15:18:07.959Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}