{"record":{"id":"4a57456113c8042e","repo":"mastra-ai/mastra","slug":"could-not-fetch-metadata-for-thread-threadid-wh","errorCode":null,"errorMessage":"Could not fetch metadata for thread ${threadId} while saving semantic recall embeddings: ${message}","messagePattern":"Could not fetch metadata for thread (.+?) while saving semantic recall embeddings: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/memory/src/index.ts","lineNumber":1398,"sourceCode":"          if (message.threadId) {\n            if (!messagesByThread.has(message.threadId)) {\n              messagesByThread.set(message.threadId, []);\n            }\n            messagesByThread.get(message.threadId)!.push(message);\n          }\n        });\n\n        const threadMetadataMap = new Map<string, Record<string, unknown>>();\n        await Promise.all(\n          Array.from(messagesByThread.keys()).map(async threadId => {\n            try {\n              const thread = await memoryStore.getThreadById({ threadId });\n              if (thread?.metadata) {\n                threadMetadataMap.set(threadId, thread.metadata);\n              }\n            } catch (error) {\n              const message = error instanceof Error ? error.message : String(error);\n              throw new Error(\n                `Could not fetch metadata for thread ${threadId} while saving semantic recall embeddings: ${message}`,\n              );\n            }\n          }),\n        );\n\n        // Collect all embeddings first (embedding is CPU-bound, doesn't use pool connections)\n        const embeddingData: Array<{\n          embeddings: number[][];\n          metadata: Array<\n            Record<string, unknown> & {\n              message_id: string;\n              thread_id: string | undefined;\n              resource_id: string | undefined;\n            }\n          >;\n        }> = [];\n        let dimension: number | undefined;","sourceCodeStart":1380,"sourceCodeEnd":1416,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/memory/src/index.ts#L1380-L1416","documentation":"While batch-saving semantic recall embeddings, Memory fetches each thread to read its metadata (needed for per-thread/per-resource embedding scoping). If that fetch throws for any thread, the original error is wrapped and rethrown with the threadId and underlying message so you know which thread and why the storage read failed.","triggerScenarios":"Calling remember() with messages whose threadId no longer resolves in the memory store while the storage adapter raises an error (connection failure, deleted table, permissions) — distinct from a plain not-found, which is tolerated.","commonSituations":"Storage DB temporarily unreachable (network blip, pool exhaustion); concurrent deletion of threads during embedding save; misconfigured storage adapter credentials; schema migrations dropping the threads table.","solutions":["Read the inner message after the colon to find the real storage error and fix it (connectivity, credentials, missing table).","Verify the memory storage adapter is healthy: run a simple getThreadById on the failing threadId against the same store.","Ensure threads are created before messages referencing them are remembered, and that concurrent jobs do not delete threads mid-save.","Retry the operation if the underlying cause was a transient connection error."],"exampleFix":"// before — silently deleting threads while saving\nawait threadsCollection.deleteOne({ id: threadId });\nawait memory.remember({ threadId, resourceId, messages });\n// after — verify thread exists first\nconst thread = await memory.getThreadById({ threadId });\nif (thread) {\n  await memory.remember({ threadId, resourceId, messages });\n}","handlingStrategy":"try-catch","validationCode":"const thread = await memory.getThreadById({ threadId });\nif (!thread) throw new Error(`Refusing to remember for missing thread ${threadId}`);","typeGuard":"function isMetadataFetchError(e: unknown, threadId: string): e is Error {\n  return e instanceof Error && e.message.includes(`Could not fetch metadata for thread ${threadId}`);\n}","tryCatchPattern":"try {\n  await memory.remember({ threadId, resourceId, messages });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Could not fetch metadata for thread')) {\n    logger.error({ err: e }, 'Storage failure while saving embeddings'); // inner message names the real cause\n    if (isTransient(e.message)) await retry(() => memory.remember({ threadId, resourceId, messages }), { retries: 3 });\n  } else throw e;\n}","preventionTips":["Monitor storage adapter health (connectivity, pool usage) since the inner error is the real cause.","Avoid deleting threads concurrently with embedding saves.","Run schema migrations for the memory store before deploying embedding-dependent code."],"tags":["memory","storage","embeddings","wrapped-error"],"backgroundTag":"storage-fetch-failure","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}