mastra-ai/mastra · error
No thread ID available. Start a session before building eval
Error message
No thread ID available. Start a session before building eval context.
What it means
buildEvalContext() needs a conversation thread ID to load messages from Mastra storage and build eval context. It resolves the thread ID from options.threadId or session.thread.getId(); if both yield nothing, no storage lookup is possible and it throws. Evals are meaningless without a persisted thread, so this is a fail-fast guard.
Source
Thrown at mastracode/sdk/src/evals/context-builder.ts:53
session: Session<any>;
/** Thread ID to build context for (defaults to current thread) */
threadId?: string;
/** Limit messages to the last N turns (user+assistant pairs). Undefined = all messages */
lastNTurns?: number;
};
/**
* Build an evaluation context from a AgentController session.
*
* This extracts messages from storage, builds trajectory from trace spans,
* and packages everything into the format scorers expect.
*/
export async function buildEvalContext(options: BuildContextOptions): Promise<MastraCodeEvalContext> {
const { controller, session, lastNTurns } = options;
const threadId = options.threadId ?? session.thread.getId();
if (!threadId) {
throw new Error('No thread ID available. Start a session before building eval context.');
}
const mastra = controller.getMastra();
const storage = mastra?.getStorage();
// 1. Get raw MastraDB messages from memory storage
const rawMessages = await getRawMessages(storage, threadId, lastNTurns);
// 2. Split messages into input/output categories
const { inputMessages, systemMessages, outputMessages } = categorizeMessages(rawMessages);
// 3. Extract trajectory from observability traces
const { trajectory, traceId } = await extractSessionTrajectory(storage, threadId);
// 4. Build request context from AgentController state
const requestContext = buildRequestContext(session, threadId);
return {View on GitHub (pinned to 75dd419e61)
Solutions
- Start a session (so a thread is created and persisted) before calling buildEvalContext.
- Pass an explicit threadId: buildEvalContext({ controller, session, threadId: existingThreadId }).
- Fetch a valid thread ID from storage/memory beforehand and assert it is truthy before invoking.
Example fix
// before
await buildEvalContext({ controller, session });
// after
const threadId = session.thread.getId?.();
if (!threadId) throw new Error('start a session first');
await buildEvalContext({ controller, session, threadId }); Defensive patterns
Strategy: validation
Validate before calling
const threadId = options.threadId ?? session.thread?.getId?.();
if (!threadId) {
throw new Error('Start a session to obtain a thread ID before building eval context.');
} Type guard
function hasThreadId(s: { thread?: { getId?: () => string | undefined } }): s is { thread: { getId: () => string } } {
return typeof s.thread?.getId?.() === 'string' && s.thread.getId().length > 0;
} Try / catch
try {
ctx = await buildEvalContext({ controller, session });
} catch (err) {
if (err instanceof Error && err.message.includes('No thread ID available')) {
await session.start(); // create the thread, then retry once
ctx = await buildEvalContext({ controller, session });
} else { throw err; }
} Prevention
- Always start a session (or pass an explicit threadId) before running evals.
- Assert thread existence in eval pipeline setup, not inside individual evals.
- Keep references to live sessions; stale/detached session objects may have no thread.
When it happens
Trigger: Calling buildEvalContext({ controller, session }) where session.thread.getId() returns undefined/null and no options.threadId was supplied — typically invoking evals before the session has started a thread.
Common situations: Running evals in a script immediately after constructing a controller without calling a session-start API; passing a stale/detached session object whose thread was never persisted; wiring evals into a pipeline that only runs after an aborted turn.
Related errors
- Invalid encrypted session data
- Invalid encrypted session data
- [MastraAuthGoogle] GOOGLE_COOKIE_PASSWORD is required for Go
- Session validation failed
- No CDP session available for page
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b629d13c4fa4c557.
Report an issue: GitHub.