affaan-m/ECC · error · Error

Memory already exists; writes are create-only.

Error message

Memory ${memory.id} already exists; writes are create-only.

What it means

Memory writes in the vault are strictly create-only: writeCreateOnlyTextFile opens the destination with exclusive-create semantics, and if the file for that memory id already exists the resulting EEXIST is converted into this explicit error. This prevents accidental overwriting or mutation of existing memories.

Solutions

  1. Use a new, unique memory id for the new memory.
  2. If the intent is to update, use the library's update path (e.g. load the existing memory via lookup/read and the update API) rather than save.
  3. Delete the existing memory file explicitly if replacement is truly intended, then save.

Example fix

// before
saveMemory({ id: 'run-2026-09-16', ... }); // second run -> EEXIST
// after
saveMemory({ id: `run-2026-09-16-${crypto.randomUUID()}`, ... });
Defensive patterns

Strategy: try-catch

Validate before calling

const dest = path.join(vaultRoot, `${memory.kind}s`, `${memory.id}.md`);
if (fs.existsSync(dest)) throw new Error(`Memory ${memory.id} already exists; pick a new id or update it.`);

Try / catch

try {
  saveMemory(memory);
} catch (err) {
  if (err.message.includes('already exists; writes are create-only')) {
    // switch to update API or generate a new id
  } else throw err;
}

Prevention

When it happens

Trigger: Calling saveMemory with a memory whose id maps to an existing <kind>s/<id>.md file in the vault root. Any second save with the same id fails, even with identical content.

Common situations: Re-running an idempotent-looking script twice; two agents generating the same memory id; assuming saveMemory behaves like an upsert when it is insert-only.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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

Appendix: source

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

  const memory = normalizeSaveInput(input || {}, options);
  const secretKinds = findPotentialSecrets(JSON.stringify(memory));
  if (secretKinds.length > 0) {
    throw new Error(`Refusing to save memory containing a suspected secret (${secretKinds.join(', ')}).`);
  }

  const root = assertMemoryRootSafe(roots, memory.scope);
  fs.mkdirSync(root, { recursive: true, mode: 0o700 });
  ensureProjectScopeIgnored(roots, memory.scope);
  const directory = path.join(root, `${memory.kind}s`);
  assertMemoryDirectorySafe(directory, root);
  fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
  const destination = path.join(directory, `${memory.id}.md`);

  try {
    writeCreateOnlyTextFile(destination, serializeMemoryDocument(memory), root);
  } catch (error) {
    if (error && error.code === 'EEXIST') {
      throw new Error(`Memory ${memory.id} already exists; writes are create-only.`);
    }
    throw error;
  }
  return { memory, path: destination };
}

function walkMemoryRoot(root, maxEntries = MAX_FILES) {
  if (!root || !fs.existsSync(root)) {
    return {
      paths: [],
      skippedSymlinks: [],
      skippedSymlinkCount: 0,
      truncated: false,
      visitedCount: 0,
    };
  }

  const paths = [];

View on GitHub (pinned to 8321021c54)