nexu-io/open-design · error · Error

failed to read memory entry after write

Error message

failed to read memory entry after write

What it means

After upsertMemoryEntry successfully wrote the .md file and updated the index, readMemoryEntry returned null when reading the entry back. This indicates the just-written file could not be found or parsed on immediate re-read, which should not happen under normal conditions.

Source

Thrown at apps/daemon/src/memory.ts:522

  });
}

export async function upsertMemoryEntry(dataDir, input, options) {
  const { name, description, type, body } = input || {};
  if (!name || !isValidType(type)) {
    throw new Error('memory entry requires `name` and a valid `type`');
  }
  const id = input?.id && /^[a-z0-9_]+$/.test(input.id)
    ? input.id
    : deriveMemoryId(type, name);
  await ensureDir(memoryDir(dataDir));
  await fsp.writeFile(
    entryPath(dataDir, id),
    renderEntryFile(name, description, type, body, options?.source ?? 'manual'),
  );
  await ensureIndexHasEntry(dataDir, id, name, description);
  const entry = await readMemoryEntry(dataDir, id);
  if (!entry) throw new Error('failed to read memory entry after write');
  if (!options?.silent) {
    emitChange({
      kind: 'upsert',
      id: entry.id,
      name: entry.name,
      description: entry.description,
      type: entry.type,
      source: options?.source ?? 'manual',
    });
  }
  return entry;
}

export async function deleteMemoryEntry(dataDir, id) {
  try {
    await fsp.unlink(entryPath(dataDir, id));
  } catch {
    // Already gone — fine. Caller doesn't care.

View on GitHub (pinned to 5be4028344)

Solutions

  1. Check filesystem permissions on the memory data directory and available disk space
  2. Verify no concurrent process is modifying or deleting memory entries
  3. Retry the upsert operation after a brief delay
  4. Check daemon logs for filesystem-level errors during the write/read cycle
Defensive patterns

Strategy: retry

Try / catch

const MAX_WRITE_RETRIES = 2;
for (let attempt = 0; attempt <= MAX_WRITE_RETRIES; attempt++) {
  try {
    return await upsertMemoryEntry(dataDir, input, options);
  } catch (err) {
    if (err.message.includes('failed to read memory entry after write') && attempt < MAX_WRITE_RETRIES) {
      await sleep(200 * (attempt + 1));
      continue;
    }
    throw err;
  }
}

Prevention

When it happens

Trigger: Filesystem permissions changed between write and read; disk full caused a partial write; antivirus/security software locked or quarantined the file; a concurrent process deleted the entry immediately after the write; the id failed entryPath validation on readback (unlikely since it was validated for write).

Common situations: Filesystem permissions issue on the data directory; disk full mid-operation; concurrent memory deletion; OS-level file locking (Windows antivirus, macOS Time Machine snapshot); NFS or network filesystem consistency delay.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/6958ea369b9b62fc. Report an issue: GitHub.