{"record":{"id":"0d1e475fd36ba572","repo":"n8n-io/n8n","slug":"observational-memory-requires-a-storage-backend-th","errorCode":null,"errorMessage":"Observational memory requires a storage backend that implements BuiltObservationLogStore.","messagePattern":"Observational memory requires a storage backend that implements BuiltObservationLogStore\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/sdk/memory.ts","lineNumber":103,"sourceCode":"}\n\nexport function resolveMemoryConfigDefaults(\n\tconfig: MemoryConfig,\n\toptions: ResolveMemoryConfigDefaultsOptions,\n): MemoryConfig {\n\tconst episodicMemory = isEpisodicMemoryEnabled(config.episodicMemory)\n\t\t? resolveEpisodicMemoryConfig(config.episodicMemory, options)\n\t\t: config.episodicMemory;\n\n\tif (!config.observationalMemory) {\n\t\treturn normalizeMemoryConfig({\n\t\t\t...config,\n\t\t\tepisodicMemory,\n\t\t});\n\t}\n\n\tif (!hasObservationLogStore(config.memory)) {\n\t\tthrow new Error(\n\t\t\t'Observational memory requires a storage backend that implements BuiltObservationLogStore.',\n\t\t);\n\t}\n\n\tconst observationalMemoryConfig =\n\t\tconfig.observationLog?.renderTokenBudget !== undefined &&\n\t\tconfig.observationalMemory.renderTokenBudget === undefined\n\t\t\t? {\n\t\t\t\t\t...config.observationalMemory,\n\t\t\t\t\trenderTokenBudget: config.observationLog.renderTokenBudget,\n\t\t\t\t}\n\t\t\t: config.observationalMemory;\n\tconst observationalMemory = resolveObservationalMemoryConfig(observationalMemoryConfig, options);\n\n\treturn normalizeMemoryConfig({\n\t\t...config,\n\t\tmemory: config.memory,\n\t\tobservationalMemory,","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/sdk/memory.ts#L85-L121","documentation":"Thrown from resolveMemoryConfigDefaults when observationalMemory is enabled but the configured storage backend (config.memory) does not implement BuiltObservationLogStore. The store capability is detected structurally via hasObservationLogStore, which checks for the six observation-log methods (appendObservationLogEntries, getActiveObservationLog, getObservationLog, dropObservationLogEntries, supersedeObservationLogEntries, applyObservationLogReflection).","triggerScenarios":"Passing a custom BuiltMemory to Memory.storage(customBackend), enabling .observationalMemory({...}), then triggering resolveMemoryConfigDefaults (typically through Agent build) — and the custom backend omits any of the observation-log methods.","commonSituations":"Bringing your own persistent backend that only implements thread/message storage; partial implementation of BuiltMemory; upgrading @n8n/agents where observational memory was added later than your backend was written.","solutions":["Use the default InMemoryMemory (omit .storage() or pass 'memory') — it implements both BuiltObservationLogStore and BuiltEpisodicMemoryStore.","Extend your custom backend to implement all six BuiltObservationLogStore methods (and the task-lock methods when needed).","If your backend cannot support observational memory, do not call .observationalMemory() on that agent's Memory builder."],"exampleFix":"// before\nconst mem = new Memory().storage(customBackend).observationalMemory({});\n// after\nconst mem = new Memory().storage('memory').observationalMemory({});","handlingStrategy":"type-guard","validationCode":"import { hasObservationLogStore } from '@n8n/agents/runtime/memory/observation-log-store';\n\nif (config.observationalMemory && !hasObservationLogStore(config.memory)) {\n  throw new Error('observational memory needs a BuiltObservationLogStore backend');\n}","typeGuard":"import { hasObservationLogStore } from '@n8n/agents/runtime/memory/observation-log-store';\n\nfunction supportsObservationalMemory(m: BuiltMemory): boolean {\n  return hasObservationLogStore(m);\n}","tryCatchPattern":null,"preventionTips":["Default to .storage('memory') unless you have a specific reason to bring a custom backend.","If you implement a custom backend, have it declare which Built*Store interfaces it implements and unit-test for them."],"tags":["memory","observational","storage","validation"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}