n8n-io/n8n · error · Error

Thread ${ref.threadId} not found in project "${project}" acr

Error message

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).

What it means

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).

Source

Thrown at packages/@n8n/instance-ai/evaluations/harness/langsmith-seed.ts:323

	}
	const tried: string[] = [];
	for (const workspace of workspaces) {
		tried.push(workspace.name);
		try {
			const result = await reconstructWithClient(
				ref,
				deps.clientForWorkspace(workspace.id),
				project,
			);
			return { ...result, sourceWorkspace: workspace.name };
		} catch (error) {
			// Not in this workspace → try the next; anything else (found but not
			// seedable, drift) is a real problem and propagates.
			if (error instanceof ThreadNotInWorkspaceError) continue;
			throw error;
		}
	}
	throw new Error(
		`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).`,
	);
}

/** Pull a thread's runs from one client/project and rebuild the seed + live turn. */
async function reconstructWithClient(
	ref: SeedThreadRef,
	client: Client,
	sourceProject: string,
): Promise<ReconstructedSeed> {
	const runs: Run[] = [];
	// Fetch only the run_types reconstruction uses — root `chain` turns + `tool` runs.
	// Paging every run_type (the llm/nested bulk is usually the majority) multiplied
	// /runs/query calls and tripped LangSmith rate limits on long threads. No is_root
	// filter: tools are non-root, so it can't be expressed as a single boolean.
	for await (const run of client.listRuns({
		projectName: sourceProject,
		filter: `and(eq(thread_id, "${ref.threadId}"), or(eq(run_type, "chain"), eq(run_type, "tool")))`,

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. If the trace aged out, recapture it (re-run the conversation in Instance AI) to mint a fresh thread id.
  2. Set seed.project on the SeedThreadRef to the project name the thread actually lives in.
  3. Confirm the key (LANGSMITH_API_KEY / _US) can access the workspace holding the trace.
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: confirm the thread has at least one run before reconstructing.
async function threadHasRuns(client: Client, ref: SeedThreadRef, project: string): Promise<boolean> {
  const runs = await client.listRuns({ threadId: ref.threadId, project, limit: 1 });
  return runs.length > 0;
}
if (!(await threadHasRuns(client, ref, project))) {
  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).`);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/17c1f370a70bfc98. Report an issue: GitHub.