CherryHQ/cherry-studio · error · McpError
InvalidParams
InvalidParams
Error message
Entity with name ${o.entityName} not found What it means
Thrown by KnowledgeGraphManager.addObservations (memory.ts:187) as an McpError(InvalidParams) when an observation entry references an entityName that is not present in the entities Map. The check is a hard throw (the alternative skip-and-warn path is commented out), so a single missing entity aborts the whole batch, including valid entries processed before it (no rollback of prior in-memory pushes, though persistence only runs after the loop).
Source
Thrown at src/main/ai/mcp/servers/memory.ts:196
}
})
if (newRelations.length > 0) {
await this._persistGraph()
}
return newRelations
}
@TraceMethod({ spanName: 'addObservtions', tag: 'KnowledgeGraph' })
async addObservations(
observations: { entityName: string; contents: string[] }[]
): Promise<{ entityName: string; addedObservations: string[] }[]> {
const results: { entityName: string; addedObservations: string[] }[] = []
let changed = false
observations.forEach((o) => {
const entity = this.entities.get(o.entityName)
if (!entity) {
// Option 1: Throw error
throw new McpError(ErrorCode.InvalidParams, `Entity with name ${o.entityName} not found`)
// Option 2: Skip and warn
// logger.warn(`Entity with name ${o.entityName} not found when adding observations. Skipping.`);
// return;
}
// Ensure observations array exists
if (!Array.isArray(entity.observations)) {
entity.observations = []
}
const newObservations = o.contents.filter((content) => !entity.observations.includes(content))
if (newObservations.length > 0) {
entity.observations.push(...newObservations)
results.push({ entityName: o.entityName, addedObservations: newObservations })
changed = true
} else {
// Still include in results even if nothing was added, to confirm processing
results.push({ entityName: o.entityName, addedObservations: [] })
}
})View on GitHub (pinned to 726446b54c)
Solutions
- Create the entity via create_entities before calling add_observations for it.
- Match the entityName exactly (case-sensitive, no leading/trailing whitespace) to the name used at creation.
- If any name in the batch may not exist, call open_nodes/read_graph first to confirm membership, or split the batch so a missing name does not abort valid ones.
- Consider filtering the batch to known entities before sending if you want partial success.
Example fix
// before
await manager.addObservations([{ entityName: 'Nonexistent', contents: ['x'] }]) // throws: Entity with name Nonexistent not found
// after
await manager.createEntities([{ name: 'Nonexistent', entityType: 'thing', observations: [] }])
await manager.addObservations([{ entityName: 'Nonexistent', contents: ['x'] }]) Defensive patterns
Strategy: validation
Validate before calling
async function safeAddObservations(manager: KnowledgeGraphManager, obs: { entityName: string; contents: string[] }[]) {
const graph = await manager.readGraph()
const known = new Set(graph.entities.map(e => e.name))
const missing = obs.filter(o => !known.has(o.entityName)).map(o => o.entityName)
if (missing.length) throw new Error(`Unknown entities (create them first): ${missing.join(', ')}`)
return manager.addObservations(obs)
} Type guard
function entityExists(graph: { entities: { name: string }[] }, name: string): boolean {
return graph.entities.some(e => e.name === name)
} Try / catch
try {
await manager.addObservations(obs)
} catch (e) {
if (e instanceof McpError && e.code === ErrorCode.InvalidParams && e.message.includes('not found')) {
// create the missing entity, then retry the batch
} else throw e
} Prevention
- Create entities before referencing them in add_observations.
- Match entityName exactly (case-sensitive, no stray whitespace) to the created name.
- Pre-validate the batch against read_graph/open_nodes to avoid aborting valid entries.
When it happens
Trigger: Calling add_observations with entityName values that were never created via create_entities, were deleted, or are misspelled. The throw fires inside the forEach, so it aborts the loop; earlier matched entities in the same batch are mutated in memory but the changed flag may not have triggered a persist yet.
Common situations: Caller creates entities and observations in separate calls but references the wrong name (case mismatch, whitespace, typo); entity was deleted in a prior step; name copied from a different graph; LLM agent invents an entity name without creating it first.
Related errors
- InternalError
- Invalid command: command must be a non-empty string
- Invalid command: command cannot be empty
- Invalid args: must be an array
- Invalid args: argument at index ${index} must be a string
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/2e3f5447ed3229e7.
Report an issue: GitHub.