affaan-m/ECC · error · Error

ECC_MEMORY_INCOMPLETE

ECC_MEMORY_INCOMPLETE

Error message

Memory lookup is incomplete. Inspect the authorized vault before retrying.

What it means

readMemoryFiles in scripts/lib/memory-vault.js walks each authorized vault scope root with walkMemoryRoot to build a complete index of memory documents. If the walk itself throws (a directory could not be opened, read, or closed), the library cannot prove the lookup saw every file, so it throws ECC_MEMORY_INCOMPLETE instead of returning silently partial results.

Solutions

  1. Fix filesystem access to the vault directory: check permissions with ls -la on ~/.claude (or the configured roots) and restore read/execute for your user.
  2. Retry the lookup — transient EIO from a network/encrypted filesystem often resolves on a second attempt.
  3. Verify the configured vault roots exist and are real directories; recreate a missing scope directory.
  4. Check for processes deleting/moving vault directories concurrently and pause them during lookups.

Example fix

// before: vault subdir unreadable -> ECC_MEMORY_INCOMPLETE
// drwx------ someuser staff memory/ but process runs as other user
sudo chown -R $(whoami) ~/.claude/ecc/memory

// after: lookup completes
const loaded = readMemoryFiles({ scopes: ['project'] });
Defensive patterns

Strategy: try-catch

Validate before calling

const fs = require('fs');
function vaultIsReadable(root) {
  try { fs.accessSync(root, fs.constants.R_OK | fs.constants.X_OK); return true; }
  catch { return false; }
}

Type guard

function canWalk(dir) {
  try { return fs.statSync(dir).isDirectory() && fs.accessSync(dir, fs.constants.R_OK) === undefined; }
  catch { return false; }
}

Try / catch

try {
  const results = searchMemories(query, { scopes: ['project'] });
} catch (e) {
  if (e.code === 'ECC_MEMORY_INCOMPLETE') {
    console.error('Vault unreadable; check permissions on the memory root, then retry.');
  } else throw e;
}

Prevention

When it happens

Trigger: readMemoryFiles (via searchMemories/loaded) calls walkMemoryRoot(root, budget) and the walk throws — e.g. EACCES/EIO opening or reading a subdirectory of the vault root, or a scope root disappearing between assertMemoryRootSafe and the walk.

Common situations: Vault directory permissions changed (chmod/chown, restrictive umask); an OS-level I/O error on a networked or encrypted home directory; another process deleting a scope directory mid-lookup; running as a different user than the vault owner.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/a6bf75f181315d91. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/memory-vault.js:475

  const skippedSymlinks = [];
  let invalidFileCount = 0;
  let skippedSymlinkCount = 0;
  let visitedCount = 0;
  let scannedBytes = 0;
  let truncated = false;

  for (const scope of scopes) {
    if (visitedCount >= MAX_FILES || scannedBytes >= MAX_SCAN_BYTES) {
      truncated = true;
      break;
    }
    const root = assertMemoryRootSafe(roots, scope);
    let walked;
    try {
      walked = walkMemoryRoot(root, MAX_FILES - visitedCount);
    } catch {
      // Directory open/read/close failures cannot establish a complete lookup.
      throw incompleteMemoryLookupError();
    }
    visitedCount += walked.visitedCount;
    truncated = truncated || walked.truncated;
    skippedSymlinkCount += walked.skippedSymlinkCount;
    for (const skippedPath of walked.skippedSymlinks) {
      if (skippedSymlinks.length >= MAX_DIAGNOSTICS) break;
      skippedSymlinks.push(vaultRelativePath(scope, root, skippedPath));
    }

    for (const filePath of walked.paths) {
      if (scannedBytes >= MAX_SCAN_BYTES) {
        truncated = true;
        break;
      }
      try {
        const source = readRegularTextFile(filePath, {
          label: 'memory document',
          maxBytes: MAX_DOCUMENT_BYTES,

View on GitHub (pinned to 8321021c54)