mastra-ai/mastra · error · HTTPException

No threadId found

Error message

No threadId found

What it means

The list-messages handler resolves an effective threadId from the path param and request context, then validates the body. If no threadId can be determined it throws HTTPException(400, 'No threadId found') before doing any lookup.

Source

Thrown at packages/server/src/server/handlers/memory.ts:1101

    mastra,
    agentId,
    threadId,
    resourceId,
    perPage,
    page,
    orderBy,
    include,
    filter,
    includeSystemReminders,
    requestContext,
  }: any) => {
    try {
      const effectiveThreadId = getEffectiveThreadId(requestContext, threadId);
      const effectiveResourceId = getEffectiveResourceId(requestContext, resourceId);
      validateBody({ threadId: effectiveThreadId });

      if (!effectiveThreadId) {
        throw new HTTPException(400, { message: 'No threadId found' });
      }

      // Gateway proxy: list messages from gateway API
      const agent = await getAgentFromContext({ mastra, agentId, requestContext });
      if (agent && (await isGatewayAgentAsync(agent))) {
        const gwClient = getGatewayClient();
        if (gwClient) {
          if (filter?.metadata && Object.keys(filter.metadata).length > 0) {
            throw new HTTPException(501, {
              message:
                'Gateway memory message metadata filters are not supported by this gateway endpoint. Remove filter.metadata or query a local memory store.',
            });
          }

          // Validate thread ownership before returning messages
          const threadResult = await gwClient.getThread(effectiveThreadId);
          if (threadResult) {
            await enforceThreadAccess({

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Pass the threadId explicitly (path param or body) in the request.
  2. Set the thread id in the request context/header the handler reads (getEffectiveThreadId) if relying on context.
  3. Check any gateway/proxy configuration that may strip custom headers.
  4. On the client, ensure a thread is created/selected before fetching its messages.

Example fix

// before
await fetch(`/api/memory/threads//messages`);
// after
if (!threadId) throw new Error('threadId required before listing messages');
await fetch(`/api/memory/threads/${threadId}/messages`);
Defensive patterns

Strategy: validation

Validate before calling

if (!threadId || typeof threadId !== 'string') {
  throw new Error('threadId is required before listing messages');
}

Type guard

function hasThreadId(v: unknown): v is { threadId: string } {
  return !!v && typeof v === 'object' && typeof (v as any).threadId === 'string' && (v as any).threadId.length > 0;
}

Try / catch

try {
  return await listMessages(threadId);
} catch (e) {
  if (isHttpException(e, 400) && /threadid/i.test(e.message)) {
    throw new UsageError('Provide a threadId (path or request context) when listing messages');
  }
  throw e;
}

Prevention

When it happens

Trigger: GET messages for a thread without supplying threadId in the request path/body and without an effectiveThreadId in the request context (e.g. missing x-mastra-thread-id style header/context value).

Common situations: Client omits the thread id when calling the messages endpoint; a proxy/gateway strips the header or context key the handler reads; SDK call constructed manually without the thread parameter.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/35703f360ad26503. Report an issue: GitHub.