{"record":{"id":"fa0a21c89cf86919","repo":"mastra-ai/mastra","slug":"memory-is-not-configured-on-this-agentcontroller","errorCode":null,"errorMessage":"Memory is not configured on this AgentController","messagePattern":"Memory is not configured on this AgentController","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/agent-controller/agent-controller.ts","lineNumber":2278,"sourceCode":"        },\n      },\n      abortSignal: session.run.getAbortSignal(),\n      emitEvent: event => session.emit(event),\n      getSubagentModelId: params => session.subagents.model.get(params ?? {}),\n    };\n\n    requestContext.set('controller', controllerContext);\n\n    return requestContext;\n  }\n\n  /**\n   * Resolve memory from config — handles both static instances and dynamic factory functions.\n   */\n  private async resolveMemory(session: Session<TState>): Promise<MastraMemory> {\n    const mem = this.config.memory;\n    if (!mem) {\n      throw new Error('Memory is not configured on this AgentController');\n    }\n    if (typeof mem !== 'function') {\n      return mem;\n    }\n    const requestContext = await this.buildRequestContext(session);\n    const resolved = await Promise.resolve(mem({ requestContext }));\n    if (!resolved) {\n      throw new Error('Dynamic memory factory returned empty value');\n    }\n    return resolved;\n  }\n\n  // ===========================================================================\n  // Token Usage\n  // ===========================================================================\n\n  private async persistTokenUsage(session: Session<TState>): Promise<void> {\n    const threadId = session.thread.getId();","sourceCodeStart":2260,"sourceCodeEnd":2296,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/agent-controller/agent-controller.ts#L2260-L2296","documentation":"resolveMemory reads this.config.memory and throws immediately when it is undefined. Memory is required for this code path but the controller was built without any memory configuration.","triggerScenarios":"Any code path calling resolveMemory (e.g. cloneThread, memory-dependent flows) on a controller whose config.memory is not set — neither a MastraMemory instance nor a factory function.","commonSituations":"Constructing AgentController with only storage, then calling an API that goes through resolveMemory (which requires config.memory specifically); environment-specific config that omits memory; typo'd config key.","solutions":["Set config.memory to a Memory instance: memory: new Memory({ storage })","Or set config.memory to a factory function ({ requestContext }) => Memory","If memory is legitimately optional, route around APIs that call resolveMemory or check config first"],"exampleFix":"// before\nnew AgentController({ storage });\n// after\nnew AgentController({ storage, memory: new Memory({ storage }) });","handlingStrategy":"validation","validationCode":"if (!controller.config.memory) throw new Error('This API requires config.memory');","typeGuard":"function hasMemory<T extends { config: { memory?: unknown } }>(c: T): c is T & { config: { memory: NonNullable<T['config']['memory']> } } {\n  return !!c.config.memory;\n}","tryCatchPattern":"try {\n  return await memoryDependentApi();\n} catch (e) {\n  if (e instanceof Error && e.message === 'Memory is not configured on this AgentController') {\n    // degrade gracefully or rethrow a domain-specific error\n  }\n  throw e;\n}","preventionTips":["Always configure memory alongside storage as a paired default","Gate memory-dependent features behind a config flag that also requires memory","Fail fast with a startup assertion instead of per-request failures"],"tags":["configuration","memory"],"backgroundTag":"memory-not-configured","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}