{"record":{"id":"26c4133bdaf09f5a","repo":"mastra-ai/mastra","slug":"dynamic-memory-factory-returned-empty-value","errorCode":null,"errorMessage":"Dynamic memory factory returned empty value","messagePattern":"Dynamic memory factory returned empty value","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/agent-controller/agent-controller.ts","lineNumber":2286,"sourceCode":"\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();\n    if (!threadId || !this.#resolveStorage()) return;\n\n    try {\n      const memoryStorage = await this.getMemoryStorage();\n      const thread = await memoryStorage.getThreadById({ threadId });\n      if (thread) {\n        await memoryStorage.saveThread({\n          thread: {","sourceCodeStart":2268,"sourceCodeEnd":2304,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/agent-controller/agent-controller.ts#L2268-L2304","documentation":"config.memory was provided as a dynamic factory function, but invoking it returned null/undefined (or a falsy value). The controller requires a concrete MastraMemory instance after resolution, so it throws to surface the misbehaving factory.","triggerScenarios":"A config.memory async/sync factory that returns undefined — e.g. it conditionally returns nothing when a lookup fails, forgets its return statement, or awaits a function that resolves to void.","commonSituations":"Factories that branch on requestContext/env and hit an implicit undefined return; returning a promise-wrapped value incorrectly; switching from a static instance to a factory during a refactor.","solutions":["Ensure the factory always returns a MastraMemory instance on every code path","Add explicit return statements / assertions inside the factory","Throw inside the factory with a descriptive error when memory cannot be constructed, instead of returning undefined"],"exampleFix":"// before\nmemory: async ({ requestContext }) => {\n  if (requestContext.get('tenant')) return buildTenantMemory(requestContext.get('tenant'));\n}\n// after\nmemory: async ({ requestContext }) => {\n  const tenant = requestContext.get('tenant');\n  if (!tenant) throw new Error('No tenant in requestContext; cannot build memory');\n  return buildTenantMemory(tenant);\n}","handlingStrategy":"type-guard","validationCode":"const resolved = await Promise.resolve(config.memory?.({ requestContext }));\nif (!resolved) throw new Error('memory factory must return a MastraMemory');","typeGuard":"function isMemory(v: unknown): v is MastraMemory {\n  return !!v && typeof (v as MastraMemory).getThreads === 'function';\n}","tryCatchPattern":"try {\n  return await resolveMemory(session);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Dynamic memory factory')) {\n    // fall back to a default memory or surface a config error\n  }\n  throw e;\n}","preventionTips":["Type the factory return as MastraMemory (not optional) so TS flags missing returns","Throw inside factories instead of returning undefined on failure paths","Unit-test the memory factory for every requestContext branch"],"tags":["configuration","memory","factory"],"backgroundTag":"factory-returned-undefined","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}