nexu-io/open-design · error · Error
memory not found
Error message
memory not found
What it means
readMemoryEntry returned null when updateMemoryTreeNode tried to load the current entry before patching it. The entry file (.md) does not exist at the expected path under the memory directory, so there is nothing to update.
Source
Thrown at apps/daemon/src/memory.ts:490
const { summary, body } = summarize(id, raw, stat.mtimeMs);
return { ...summary, body };
}
function renderEntryFile(name, description, type, body, source) {
const safeName = String(name || 'Untitled').replace(/\r?\n/g, ' ').trim();
const safeDesc = String(description || '').replace(/\r?\n/g, ' ').trim();
const safeType = isValidType(type) ? type : 'user';
const safeSource = VALID_SOURCES.has(source) ? source : 'manual';
const trimmedBody = String(body || '').replace(/^\s+/, '');
return `---\nname: ${safeName}\ndescription: ${safeDesc}\ntype: ${safeType}\nsource: ${safeSource}\n---\n\n${trimmedBody}\n`;
}
export async function updateMemoryTreeNode(dataDir, id, patch) {
if (typeof id !== 'string' || id.startsWith('folder:')) {
throw new Error('memory tree folders are derived and cannot be edited');
}
const current = await readMemoryEntry(dataDir, id);
if (!current) throw new Error('memory not found');
const nextType = isValidType(patch?.type) ? patch.type : current.type;
return upsertMemoryEntry(dataDir, {
id,
name:
typeof patch?.name === 'string' && patch.name.trim()
? patch.name
: current.name,
description:
typeof patch?.description === 'string'
? patch.description
: current.description,
type: nextType,
body: typeof patch?.body === 'string' ? patch.body : current.body,
});
}
export async function upsertMemoryEntry(dataDir, input, options) {
const { name, description, type, body } = input || {};View on GitHub (pinned to 5be4028344)
Solutions
- Verify the entry id exists by listing current memory entries before attempting to update
- Refresh the memory list to get the current set of valid entry ids
- If the entry should exist, create it first via upsertMemoryEntry instead of updating
- Check for concurrent memory modification operations
Defensive patterns
Strategy: validation
Validate before calling
// Check entry existence before updating
import { readMemoryEntry } from './memory';
async function assertMemoryEntryExists(dataDir, id) {
const entry = await readMemoryEntry(dataDir, id);
if (!entry) {
throw new Error(`Memory entry not found: ${id}. It may have been deleted. Refresh the list and try again.`);
}
return entry;
} Try / catch
try {
await updateMemoryTreeNode(dataDir, id, patch);
} catch (err) {
if (err.message === 'memory not found') {
// Entry was deleted — offer to create instead
return upsertMemoryEntry(dataDir, { id, ...patch });
}
throw err;
} Prevention
- Refresh the memory entry list before allowing edits to avoid stale ids
- Handle concurrent deletion gracefully by falling back to create-if-missing semantics
- Use optimistic concurrency checks if multiple clients can modify memory entries simultaneously
When it happens
Trigger: Calling updateMemoryTreeNode with an id that was never created; the entry was deleted between the UI listing it and the update attempt; a concurrent process removed the .md file; filesystem issue prevented reading.
Common situations: Stale UI showing an entry that was deleted elsewhere; race condition between a delete and an update on the same entry; manual filesystem cleanup removed memory .md files; the id was fabricated by the caller and never corresponded to a real entry.
Related errors
- delete proposal requires targetRef
- automation proposal not found
- brand not found: ${opts.id}
- brand backing project not found: ${projectId}
- brand not found: ${id}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/e631ecc346dea51b.
Report an issue: GitHub.