modelcontextprotocol/servers · error
Entity with name ${r.from} not found
Error message
Entity with name ${r.from} not found What it means
MemoryServerGraph.createRelations() validates every requested relation against the set of entity names currently in the persisted knowledge graph before writing. If a relation's 'from' endpoint names an entity that does not exist, it throws immediately and no relations from the batch are created (the whole operation is atomic under the graph lock). The library refuses dangling relations so the graph never contains edges to or from nonexistent nodes.
Source
Thrown at src/memory/index.ts:223
const newEntities = entities.filter((e, index) =>
!graph.entities.some(existingEntity => existingEntity.name === e.name) &&
// Also skip duplicates appearing earlier in this same batch
!entities.slice(0, index).some(earlier => earlier.name === e.name)
);
graph.entities.push(...newEntities);
await this.saveGraph(graph);
return newEntities;
});
}
async createRelations(relations: Relation[]): Promise<Relation[]> {
return this.withLock(async () => {
const graph = await this.loadGraph();
const entityNames = new Set(graph.entities.map(e => e.name));
relations.forEach(r => {
if (!entityNames.has(r.from)) {
throw new Error(`Entity with name ${r.from} not found`);
}
if (!entityNames.has(r.to)) {
throw new Error(`Entity with name ${r.to} not found`);
}
});
const isSameRelation = (a: Relation, b: Relation) =>
a.from === b.from &&
a.to === b.to &&
a.relationType === b.relationType;
const newRelations = relations.filter((r, index) =>
!graph.relations.some(existingRelation => isSameRelation(existingRelation, r)) &&
// Also skip duplicates appearing earlier in this same batch
!relations.slice(0, index).some(earlier => isSameRelation(earlier, r))
);
graph.relations.push(...newRelations);
await this.saveGraph(graph);
return newRelations;View on GitHub (pinned to d73f99efbf)
Solutions
- Ensure all referenced entities exist first by calling createEntities with the same names before createRelations.
- Load the current graph (readGraphFile / loadGraph) and diff your relation endpoints against entity names before submitting.
- Check for exact string equality (case, trimming) between the 'from' name and the entity name used at creation time.
- Catch the error and report which endpoint is missing rather than retrying blindly — retries will keep failing until the entity exists.
Example fix
// before
await memory.createRelations([{ from: "alice", to: "Bob", relationType: "knows" }]);
// after
await memory.createEntities([{ name: "alice", entityType: "person", observations: [] }]);
await memory.createRelations([{ from: "alice", to: "Bob", relationType: "knows" }]); Defensive patterns
Strategy: validation
Validate before calling
const graph = await memory.readGraph();
const names = new Set(graph.entities.map(e => e.name));
const missing = relations.filter(r => !names.has(r.from) || !names.has(r.to));
if (missing.length) throw new Error(`Missing entities: ${[...new Set(missing.flatMap(r => [r.from, r.to]))].filter(n => !names.has(n)).join(", ")}`);
await memory.createRelations(relations); Type guard
function allEndpointsExist(relations: Relation[], names: Set<string>): boolean {
return relations.every(r => names.has(r.from) && names.has(r.to));
} Try / catch
try {
await memory.createRelations(relations);
} catch (e) {
if (e instanceof Error && e.message.includes("not found")) {
const name = e.message.match(/Entity with name (.+) not found/)?.[1];
await memory.createEntities([{ name: name!, entityType: "unknown", observations: [] }]);
await memory.createRelations(relations);
} else throw e;
} Prevention
- Always create entities before relations in the same workflow.
- Keep entity names in a shared constant/enum to avoid typos and case drift.
- Diff intended relations against a fresh graph read before each batch write.
When it happens
Trigger: Calling createRelations([ { from: 'Alice', to: 'Bob', relationType: 'knows' } ]) when no entity named 'Alice' has been created via createEntities in the same graph file, or after the graph file was deleted/replaced, or when the entity name differs in case/whitespace from the stored one.
Common situations: Creating relations and entities in separate calls and passing wrong entity names; restoring a graph.json from a backup that lacks recently added entities; typos or case mismatches between createEntities and createRelations payloads; clients batching relations before the entity-creation call completes.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Entity with name ${r.to} not found
- Access denied - parent directory outside allowed directories
- Parent directory does not exist: ${parentDir}
- Invalid resourceType: ${args?.resourceType}. Must be ${RESOU
- Invalid resourceId: ${args?.resourceId}. Must be a finite po
AI-assisted analysis of modelcontextprotocol/servers@d73f99efbf (2026-09-07).
Data as JSON: /api/errors/a15f0c53f860a4fe.
Report an issue: GitHub.