{"record":{"id":"17c1f370a70bfc98","repo":"n8n-io/n8n","slug":"thread-ref-threadid-not-found-in-project-pro","errorCode":null,"errorMessage":"Thread ${ref.threadId} not found in project \"${project}\" across ${String(workspaces.length)} workspace(s): ${tried.join(', ')}. The trace may have aged out (~14-day base retention), or the project name differs (set seed.project).","messagePattern":"Thread (.+?) not found in project \"(.+?)\" across (.+?) workspace\\(s\\): (.+?)\\. The trace may have aged out \\(~14-day base retention\\), or the project name differs \\(set seed\\.project\\)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/instance-ai/evaluations/harness/langsmith-seed.ts","lineNumber":323,"sourceCode":"\t}\n\tconst tried: string[] = [];\n\tfor (const workspace of workspaces) {\n\t\ttried.push(workspace.name);\n\t\ttry {\n\t\t\tconst result = await reconstructWithClient(\n\t\t\t\tref,\n\t\t\t\tdeps.clientForWorkspace(workspace.id),\n\t\t\t\tproject,\n\t\t\t);\n\t\t\treturn { ...result, sourceWorkspace: workspace.name };\n\t\t} catch (error) {\n\t\t\t// Not in this workspace → try the next; anything else (found but not\n\t\t\t// seedable, drift) is a real problem and propagates.\n\t\t\tif (error instanceof ThreadNotInWorkspaceError) continue;\n\t\t\tthrow error;\n\t\t}\n\t}\n\tthrow new Error(\n\t\t`Thread ${ref.threadId} not found in project \"${project}\" across ${String(workspaces.length)} workspace(s): ${tried.join(', ')}. The trace may have aged out (~14-day base retention), or the project name differs (set seed.project).`,\n\t);\n}\n\n/** Pull a thread's runs from one client/project and rebuild the seed + live turn. */\nasync function reconstructWithClient(\n\tref: SeedThreadRef,\n\tclient: Client,\n\tsourceProject: string,\n): Promise<ReconstructedSeed> {\n\tconst runs: Run[] = [];\n\t// Fetch only the run_types reconstruction uses — root `chain` turns + `tool` runs.\n\t// Paging every run_type (the llm/nested bulk is usually the majority) multiplied\n\t// /runs/query calls and tripped LangSmith rate limits on long threads. No is_root\n\t// filter: tools are non-root, so it can't be expressed as a single boolean.\n\tfor await (const run of client.listRuns({\n\t\tprojectName: sourceProject,\n\t\tfilter: `and(eq(thread_id, \"${ref.threadId}\"), or(eq(run_type, \"chain\"), eq(run_type, \"tool\")))`,","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/instance-ai/evaluations/harness/langsmith-seed.ts#L305-L341","documentation":"Thrown by discoverAndReconstruct() after iterating every accessible workspace and finding the referenced thread in none of them (each attempt threw ThreadNotInWorkspaceError). The error lists the project, the workspace count, and every workspace name tried. The two root causes are called out in the message: the trace may have aged out (LangSmith ~14-day base retention), or the project name differs from what the thread actually lives in (overridable via seed.project).","triggerScenarios":"Reconstructing a seed from a thread id whose trace has expired in LangSmith; the thread lives in a project whose name is not DEFAULT_SOURCE_PROJECT and seed.project was not set; the thread belongs to a workspace the key cannot enumerate.","commonSituations":"Trace older than ~14 days; thread id from a different LangSmith project; org key lacks the workspace holding the trace; typo in the thread id.","solutions":["If the trace aged out, recapture it (re-run the conversation in Instance AI) to mint a fresh thread id.","Set seed.project on the SeedThreadRef to the project name the thread actually lives in.","Confirm the key (LANGSMITH_API_KEY / _US) can access the workspace holding the trace."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-flight: confirm the thread has at least one run before reconstructing.\nasync function threadHasRuns(client: Client, ref: SeedThreadRef, project: string): Promise<boolean> {\n  const runs = await client.listRuns({ threadId: ref.threadId, project, limit: 1 });\n  return runs.length > 0;\n}\nif (!(await threadHasRuns(client, ref, project))) {\n  throw new Error(`Thread ${ref.threadId} has no runs in project \"${project}\". Trace may have aged out (~14d) or project name differs (set seed.project).`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Re-capture fresh traces before the ~14-day LangSmith retention window closes.","Set seed.project on the SeedThreadRef when the thread lives outside DEFAULT_SOURCE_PROJECT.","Confirm the LANGSMITH key can enumerate the workspace holding the trace."],"tags":["langsmith","thread","trace-retention","workspace-discovery"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}