EveryInc/compound-engineering-plugin · error · Error

Could not validate ${collectionPath} after taking it. The en

Error message

Could not validate ${collectionPath} after taking it. The entry is preserved at ${recoveryPath} (${reason})

What it means

removeManagedCollectionLink() moves the entry to a temp recovery directory and hands it to options.onTakenForTest for post-removal validation. If that callback throws, the original entry is kept at recoveryPath and the code re-raises with its location so nothing is lost. This is a safety net ensuring the 'taken' entry is never silently dropped when validation cannot complete.

Source

Thrown at src/dev/codex-dev.ts:316

  const parentPath = path.dirname(collectionPath)
  const recoveryDir = await fs.mkdtemp(
    path.join(parentPath, `.${path.basename(collectionPath)}.recovery-`),
  )
  const recoveryPath = path.join(recoveryDir, "entry")

  try {
    await fs.rename(collectionPath, recoveryPath)
  } catch (error) {
    await fs.rmdir(recoveryDir).catch(() => undefined)
    if ((error as NodeJS.ErrnoException).code === "ENOENT") return changed()
    throw error
  }

  try {
    await options.onTakenForTest?.(recoveryPath)
  } catch (error) {
    const reason = error instanceof Error ? error.message : String(error)
    throw new Error(
      `Could not validate ${collectionPath} after taking it. ` +
        `The entry is preserved at ${recoveryPath} (${reason})`,
    )
  }

  const stat = await fs.lstat(recoveryPath)
  let actualTarget: string | undefined
  if (stat.isSymbolicLink()) {
    actualTarget = await fs.readlink(recoveryPath)
  }

  if (stat.isSymbolicLink() && actualTarget === expectedTarget) {
    await fs.unlink(recoveryPath)
    await fs.rmdir(recoveryDir)
    return true
  }

  const restorationFailed = (error: unknown): never => {

View on GitHub (pinned to c9c10f8c75)

Solutions

  1. Read the recoveryPath from the error message — the original entry is intact there
  2. Check free space and write permissions on the OS temp directory used for recoveryPath
  3. Manually move the entry back: `mv <recoveryPath> <collectionPath>` to restore the previous state
  4. Re-run the removal after fixing the underlying validation failure

Example fix

// before — recovery dir unwritable, callback fails
// Error: Could not validate ... (EACCES: permission denied, scandir '/tmp/...')

// after
$ TMPDIR=/tmp  # or fix perms on the configured temp dir
$ mv "$recoveryPath" "$collectionPath" && retry the codex:dev command
Defensive patterns

Strategy: try-catch

Validate before calling

import { fs } from "...";
await fs.access(path.dirname(recoveryPath)); // recovery dir is readable
const stat = await fs.stat(recoveryPath);     // taken entry actually exists

Try / catch

try {
  await removeLocalCollection(context);
} catch (e) {
  const m = String(e).match(/preserved at (\S+)/);
  if (m) console.error(`original entry kept at ${m[1]}; restore manually if needed`);
  else throw e;
}

Prevention

When it happens

Trigger: The onTakenForTest callback supplied by replaceManagedCollectionLink / restoreLocalCollection / removeLocalCollection throws — any filesystem error while validating or restoring the taken entry (permission denied, ENOENT on the recovery path, disk full).

Common situations: Temp directory on a read-only or full volume so the recovery copy cannot be read back; sandbox/permissions blocking access to the mkdtemp recovery directory; a bug in the caller's validation callback throwing spuriously.

Related errors


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