{"record":{"id":"2e3f5447ed3229e7","repo":"CherryHQ/cherry-studio","slug":"invalidparams-2e3f54","errorCode":"InvalidParams","errorMessage":"Entity with name ${o.entityName} not found","messagePattern":"Entity with name (.+?) not found","errorType":"exception","errorClass":"McpError","httpStatus":null,"severity":"error","filePath":"src/main/ai/mcp/servers/memory.ts","lineNumber":196,"sourceCode":"      }\n    })\n    if (newRelations.length > 0) {\n      await this._persistGraph()\n    }\n    return newRelations\n  }\n\n  @TraceMethod({ spanName: 'addObservtions', tag: 'KnowledgeGraph' })\n  async addObservations(\n    observations: { entityName: string; contents: string[] }[]\n  ): Promise<{ entityName: string; addedObservations: string[] }[]> {\n    const results: { entityName: string; addedObservations: string[] }[] = []\n    let changed = false\n    observations.forEach((o) => {\n      const entity = this.entities.get(o.entityName)\n      if (!entity) {\n        // Option 1: Throw error\n        throw new McpError(ErrorCode.InvalidParams, `Entity with name ${o.entityName} not found`)\n        // Option 2: Skip and warn\n        // logger.warn(`Entity with name ${o.entityName} not found when adding observations. Skipping.`);\n        // return;\n      }\n      // Ensure observations array exists\n      if (!Array.isArray(entity.observations)) {\n        entity.observations = []\n      }\n      const newObservations = o.contents.filter((content) => !entity.observations.includes(content))\n      if (newObservations.length > 0) {\n        entity.observations.push(...newObservations)\n        results.push({ entityName: o.entityName, addedObservations: newObservations })\n        changed = true\n      } else {\n        // Still include in results even if nothing was added, to confirm processing\n        results.push({ entityName: o.entityName, addedObservations: [] })\n      }\n    })","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/mcp/servers/memory.ts#L178-L214","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait manager.addObservations([{ entityName: 'Nonexistent', contents: ['x'] }]) // throws: Entity with name Nonexistent not found\n\n// after\nawait manager.createEntities([{ name: 'Nonexistent', entityType: 'thing', observations: [] }])\nawait manager.addObservations([{ entityName: 'Nonexistent', contents: ['x'] }])","handlingStrategy":"validation","validationCode":"async function safeAddObservations(manager: KnowledgeGraphManager, obs: { entityName: string; contents: string[] }[]) {\n  const graph = await manager.readGraph()\n  const known = new Set(graph.entities.map(e => e.name))\n  const missing = obs.filter(o => !known.has(o.entityName)).map(o => o.entityName)\n  if (missing.length) throw new Error(`Unknown entities (create them first): ${missing.join(', ')}`)\n  return manager.addObservations(obs)\n}","typeGuard":"function entityExists(graph: { entities: { name: string }[] }, name: string): boolean {\n  return graph.entities.some(e => e.name === name)\n}","tryCatchPattern":"try {\n  await manager.addObservations(obs)\n} catch (e) {\n  if (e instanceof McpError && e.code === ErrorCode.InvalidParams && e.message.includes('not found')) {\n    // create the missing entity, then retry the batch\n  } else throw e\n}","preventionTips":["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."],"tags":["mcp","memory-server","validation","knowledge-graph","mcp-error"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}