{"record":{"id":"993d7439e12c2a31","repo":"mastra-ai/mastra","slug":"thread-requestedthreadid-not-found","errorCode":null,"errorMessage":"thread \"${requestedThreadId}\" not found","messagePattern":"thread \"(.+?)\" not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"packages/server/src/server/handlers/agent-controller.ts","lineNumber":820,"sourceCode":"  pathParamSchema: sessionPathParams,\n  queryParamSchema: sessionStateQuerySchema,\n  responseSchema: sessionStateResponseSchema,\n  summary: 'Get session state',\n  description: 'Returns the current mode, model, thread, and durable tasks for initial UI hydration.',\n  tags: ['AgentController'],\n  requiresAuth: true,\n  requiresPermission: 'agent-controller:read',\n  handler: async ({ mastra, controllerId, resourceId, sessionScope, threadId: requestedThreadId, requestContext }) => {\n    try {\n      const controller = getAgentControllerOrThrow(mastra, controllerId);\n      const session = await getSession(controller, resourceId, { scope: sessionScope }, requestContext);\n      const ds = session.displayState.get();\n      const threadId = requestedThreadId ?? session.thread.getId() ?? undefined;\n      const storage = mastra.getStorage();\n      if (requestedThreadId) {\n        const memory = await storage?.getStore('memory');\n        const thread = await memory?.getThreadById({ threadId: requestedThreadId, resourceId });\n        if (!thread) throw new HTTPException(404, { message: `thread \"${requestedThreadId}\" not found` });\n      }\n      const threadState = threadId ? await storage?.getStore('threadState') : undefined;\n      const storedTasks = threadId ? await threadState?.getState<unknown>({ threadId, type: 'task' }) : undefined;\n      const parsedTasks = taskSnapshotSchema.array().safeParse(storedTasks);\n      const tasks: SessionTaskSnapshot[] = parsedTasks.success ? parsedTasks.data : [];\n      const om = ds.omProgress;\n      const reflectionSavings =\n        om.buffered.reflection.inputObservationTokens - om.buffered.reflection.observationTokens;\n      const st = session.state.get() as Record<string, unknown>;\n      const oneOf = <T extends string>(value: unknown, allowed: readonly T[], fallback: T): T =>\n        allowed.includes(value as T) ? (value as T) : fallback;\n      const oneOfOptional = <T extends string>(value: unknown, allowed: readonly T[]): T | undefined =>\n        allowed.includes(value as T) ? (value as T) : undefined;\n      return {\n        controllerId,\n        resourceId,\n        threadId,\n        modeId: session.mode.get(),","sourceCodeStart":802,"sourceCodeEnd":838,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/agent-controller.ts#L802-L838","documentation":"When a session endpoint is called with an explicit `requestedThreadId`, the handler loads the thread via the memory store scoped to the given resourceId and throws HTTP 404 if no matching thread exists. This ensures clients cannot attach a session to a nonexistent (or other-resource) thread.","triggerScenarios":"Passing a threadId in the request body/params that was never created, was deleted, belongs to a different resourceId (resource scoping is applied in getThreadById), or whose storage backend changed (e.g. switched storage domains and old thread ids no longer resolve).","commonSituations":"Client caches thread ids across environments (dev vs prod storage); in-memory storage reset on server restart so old ids vanish; resourceId mismatch because the identity/resource changed; typos in persisted thread id.","solutions":["Verify the threadId exists and belongs to the same resourceId — drop the explicit threadId to let the session create/reuse its own thread.","Create the thread first (via the session/thread creation endpoint) before referencing it.","Check storage configuration: ensure the memory store backing the server is the one that contains the thread.","Clear stale client-side thread id caches after restarts or storage migrations."],"exampleFix":"// before\nconst s = await api.createSession({ resourceId, threadId: savedThreadId }); // 404 after storage reset\n// after\nconst s = await api.createSession({ resourceId }); // let server create/reuse a thread","handlingStrategy":"try-catch","validationCode":"const thread = await memoryClient.getThreadById({ threadId: requestedThreadId, resourceId });\nif (!thread) throw new Error(`Thread ${requestedThreadId} does not exist for ${resourceId}; omit threadId to create one`);","typeGuard":"function threadExists(t: { id: string } | null | undefined, id: string): t is { id: string } {\n  return !!t && t.id === id;\n}","tryCatchPattern":"try {\n  session = await api.createSession({ resourceId, threadId: requestedThreadId });\n} catch (e) {\n  if (isHttpError(e) && e.status === 404 && e.message.includes('not found')) {\n    session = await api.createSession({ resourceId }); // create a fresh thread\n  } else throw e;\n}","preventionTips":["Don't persist thread ids across storage resets or environments.","Always pass the resourceId that owns the thread.","Fall back to server-created threads instead of assuming ids."],"tags":["http-404","thread","memory","not-found"],"backgroundTag":"thread-not-found","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}