{"record":{"id":"c7affb59b11f0a09","repo":"mastra-ai/mastra","slug":"knowledge-node-not-found-value-node","errorCode":null,"errorMessage":"Knowledge node not found: ${value.node}","messagePattern":"Knowledge node not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/memory/src/processors/observational-memory/subconscious/knowledge-write-tools.ts","lineNumber":71,"sourceCode":"    knowledge_append: createTool({\n      id: 'knowledge_append',\n      description: 'Append a scoped record to an existing node. Provenance and capture time are stamped by code.',\n      inputSchema: {\n        type: 'object',\n        properties: {\n          node: { type: 'string', minLength: 1 },\n          text: { type: 'string', minLength: 1 },\n          scope: scopeLevelSchema,\n          when: { type: 'string' },\n        },\n        required: ['node', 'text'],\n        additionalProperties: false,\n      } satisfies JSONSchema7,\n      execute: async input => {\n        const value = input as { node: string; text: string; scope?: KnowledgeScopeLevel; when?: string };\n        const store = await getStore(memory);\n        const parent = await store.getNode(value.node);\n        if (!parent || parent.mergedInto) throw new Error(`Knowledge node not found: ${value.node}`);\n        requireVisible(parent.scope, options, 'Knowledge node');\n        const scope = resolveWriteScope(options, value.scope);\n        const when = value.when ? new Date(value.when) : undefined;\n        if (when && Number.isNaN(when.getTime())) throw new Error('KnowledgeRecord when must be a valid date.');\n        return store.appendKnowledge({\n          node: parent.id,\n          text: value.text,\n          scope,\n          sourceThreadId: options.sourceThreadId,\n          when,\n          maxScope: options.maxScope,\n          resolutionScope: options.scope,\n          defaultScope: expandKnowledgeScope(options.scope, options.defaultScope),\n        });\n      },\n    }),\n    knowledge_remove: createTool({\n      id: 'knowledge_remove',","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/memory/src/processors/observational-memory/subconscious/knowledge-write-tools.ts#L53-L89","documentation":"knowledge_append appends a record to an existing parent node; it never creates nodes. Before writing, the handler loads the node by the provided `node` ID and throws this error when the node is missing OR when it has been merged into another node (mergedInto set), since merged nodes are tombstones and no longer accept records. The error message includes the offending node identifier.","triggerScenarios":"Calling knowledge_append with a node ID that does not exist, was deleted, or was merged away by knowledge_merge_nodes; LLM inventing node IDs; reusing a cached ID after a merge.","commonSituations":"After a duplicate-node merge, agents still reference the source node's old ID; stale IDs from earlier sessions or other tenants; typo'd IDs copied from logs.","solutions":["Re-resolve the node by name via knowledge_read { name } or resolveNode within the current scope to get its current ID.","If the node was merged, append to the surviving target node (follow mergedInto).","Create the node first with knowledge_write_node_content when it genuinely doesn't exist.","Instruct the agent to look up node IDs with knowledge_search/knowledge_read before appending."],"exampleFix":"// before\nawait tools.knowledge_append.execute({ node: 'merged_or_missing_node', text: 'note' }, ctx);\n// after\nconst node = await tools.knowledge_read.execute({ name: 'Deployment Guide' }, ctx);\nif (node.found) await tools.knowledge_append.execute({ node: node.id, text: 'note' }, ctx);","handlingStrategy":"validation","validationCode":"const parent = await tools.knowledge_read.execute({ id: nodeId }, ctx);\nif (!parent.found || (parent as any).mergedInto) {\n  throw new Error(`Cannot append: node ${nodeId} is missing or merged.`);\n}","typeGuard":"function isAppendableNode(n: unknown): n is { id: string; mergedInto: undefined } {\n  const x = n as { id?: string; mergedInto?: string | undefined };\n  return typeof x?.id === 'string' && x.mergedInto === undefined;\n}","tryCatchPattern":"try {\n  return await curatorTools.knowledge_append.execute(args, {} as any);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Knowledge node not found:')) {\n    const nodeId = e.message.slice('Knowledge node not found: '.length);\n    const live = await resolveNodeByName(nodeId);\n    if (live) return curatorTools.knowledge_append.execute({ ...args, node: live.id }, {} as any);\n  }\n  throw e;\n}","preventionTips":["Resolve nodes by name in the current scope instead of reusing cached IDs.","After knowledge_merge_nodes, update all references to the surviving target ID.","Create nodes explicitly with knowledge_write_node_content before appending.","Instruct agents to read a node first when unsure of its ID."],"tags":["knowledge-append","entity-not-found","merged-node","stale-reference"],"backgroundTag":"entity-not-found","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}