EveryInc/compound-engineering-plugin · warning
Ignoring unreadable install manifest at ${manifestPath}.
Error message
Ignoring unreadable install manifest at ${manifestPath}. What it means
This warning is emitted by readManagedInstallManifest when the managed install manifest file exists but cannot be parsed or read (any error other than ENOENT). The library treats a corrupt/unreadable manifest as absent and returns null, warning instead of throwing so installation can proceed with a fresh manifest. It exists because users may hand-edit or partially delete the manifest.
Source
Thrown at src/targets/managed-artifacts.ts:138
const safeGroups: Record<string, string[]> = {}
for (const [group, entries] of Object.entries(parsed.groups)) {
const safe: string[] = []
for (const entry of entries as unknown[]) {
if (isSafeManagedPath(managedDir, entry)) {
safe.push(entry)
} else {
console.warn(
`Dropping unsafe install-manifest entry in ${manifestPath} (group "${group}"): ${JSON.stringify(entry)}`,
)
}
}
safeGroups[group] = safe
}
return { version: 1, pluginName, groups: safeGroups }
}
} catch (err) {
if ((err as NodeJS.ErrnoException).code !== "ENOENT") {
console.warn(`Ignoring unreadable install manifest at ${manifestPath}.`)
}
}
return null
}
export async function writeManagedInstallManifest(
managedDir: string,
manifest: ManagedInstallManifest,
): Promise<void> {
await writeJson(path.join(managedDir, MANAGED_INSTALL_MANIFEST), manifest)
}
export async function cleanupRemovedManagedDirectories(
rootDir: string,
manifest: ManagedInstallManifest | null,
group: string,
currentEntries: string[],
): Promise<void> {View on GitHub (pinned to c9c10f8c75)
Solutions
- Delete the corrupt manifest file so the next run treats it as absent (ENOENT) and writes a fresh one.
- Check file permissions on manifestPath so the current user can read it.
- Validate the JSON content of the manifest with a JSON parser and fix syntax errors.
- Reinstall the plugin to regenerate a valid manifest.
Example fix
// before cat ~/.mytool/manifest.json // truncated JSON -> warning // after rm ~/.mytool/manifest.json // treated as ENOENT, manifest regenerated
Defensive patterns
Strategy: fallback
Validate before calling
import { readFile } from "node:fs/promises";
async function manifestReadable(path: string) {
try {
const raw = await readFile(path, "utf8");
JSON.parse(raw);
return true;
} catch (err: any) {
if (err?.code === "ENOENT") return true; // absent is fine
return false;
}
} Type guard
function isManifestJson(v: unknown): v is { version: number; groups: Record<string, unknown> } {
return (
typeof v === "object" && v !== null &&
"version" in v && typeof (v as any).version === "number"
);
} Try / catch
// readManagedInstallManifest never throws; it returns null on unreadable manifests
const manifest = await readManagedInstallManifest(manifestPath);
if (manifest === null) {
// absent or corrupt: proceed as fresh install; expect writeManagedInstallManifest to recreate it
} Prevention
- Do not hand-edit the install manifest; let the tool write it.
- Avoid interrupting installs mid-write (no Ctrl-C during install).
- Keep ~/.config paths owned and readable by the running user.
- Delete a corrupt manifest rather than partially repairing it.
When it happens
Trigger: Calling readManagedInstallManifest (or readManagedInstallManifestWithLegacyFallback / owned / current) when the manifest at manifestPath exists but contains invalid JSON, has wrong permissions, or the read fails with an I/O error other than ENOENT.
Common situations: A partially written manifest after a crashed install; manual editing that broke JSON; permission changes on ~/.config paths; a manifest written by an older incompatible version of the tool.
Related errors
- Ignoring unreadable Pi install manifest at ${manifestPath}.
- Local plugin path not found: ${directPath}
- Local plugin path not found: ${directPath}
- Plugin directory not found: ${pluginPath}
- Could not read ${filePath}: ${error instanceof Error ? error
AI-assisted analysis of EveryInc/compound-engineering-plugin@c9c10f8c75 (2026-08-31).
Data as JSON: /api/errors/d90ab020a0a8c25b.
Report an issue: GitHub.