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

  1. Delete the corrupt manifest file so the next run treats it as absent (ENOENT) and writes a fresh one.
  2. Check file permissions on manifestPath so the current user can read it.
  3. Validate the JSON content of the manifest with a JSON parser and fix syntax errors.
  4. 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

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


AI-assisted analysis of EveryInc/compound-engineering-plugin@c9c10f8c75 (2026-08-31). Data as JSON: /api/errors/d90ab020a0a8c25b. Report an issue: GitHub.