mastra-ai/mastra · error · HTTPException

resourceId is required

Error message

resourceId is required

What it means

The buffer-status request omitted resourceId. Even in resource-scoped OM (where threadId is ignored), the record is keyed by resource, so the handler requires a non-empty resourceId before reading the OM record from storage.

Source

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

      // After buffering, fetch the updated record
      const memory = await getMemoryFromContext({ mastra, agentId, requestContext });
      if (!memory) {
        throw new HTTPException(400, { message: 'Memory is not configured for this agent' });
      }

      let memoryStore: MemoryStorage | undefined;
      try {
        memoryStore = await memory.storage.getStore('memory');
      } catch {
        throw new HTTPException(400, { message: 'Memory storage is not initialized' });
      }
      if (!memoryStore) {
        throw new HTTPException(400, { message: 'Memory storage is not initialized' });
      }

      const effectiveResourceId = resourceId;
      if (!effectiveResourceId) {
        throw new HTTPException(400, { message: 'resourceId is required' });
      }

      const omThreadId = omConfig.scope === 'resource' ? null : (threadId ?? null);
      const record = await memoryStore.getObservationalMemory(omThreadId, effectiveResourceId);

      return { record: record ?? null };
    } catch (error) {
      console.error('Error awaiting buffer status', error);
      return handleError(error, 'Error awaiting buffer status');
    }
  },
});

export const LIST_THREADS_ROUTE = createRoute({
  method: 'GET',
  path: '/memory/threads',
  responseType: 'json',
  queryParamSchema: listThreadsQuerySchema,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Include resourceId in the request body alongside agentId and threadId.
  2. Defer polling until the resource id exists (after first message/resource creation).
  3. Validate the body client-side and skip the call when resourceId is falsy, treating buffering as not started.

Example fix

// before
body: JSON.stringify({ agentId, threadId })
// after
body: JSON.stringify({ agentId, threadId, resourceId })
Defensive patterns

Strategy: validation

Validate before calling

if (!resourceId) {
  // resource not created yet; treat buffering as not started
  return { record: null };
}
await fetch('/api/memory/observational-memory/buffer-status', {
  method: 'POST',
  body: JSON.stringify({ agentId, threadId, resourceId }),
});

Type guard

function canPollBufferStatus(p: { agentId?: string; threadId?: string; resourceId?: string }): p is { agentId: string; threadId: string; resourceId: string } {
  return !!(p.agentId && p.threadId && p.resourceId);
}

Try / catch

try {
  return await pollBufferStatus(params);
} catch (e) {
  if (isHttpError(e, 400) && /resourceId is required/.test(e.message)) {
    return { record: null }; // resource not established yet
  }
  throw e;
}

Prevention

When it happens

Trigger: POST /api/memory/observational-memory/buffer-status with agentId/threadId but no resourceId in the body — e.g. polling starts before the resource is created on a 'new chat' screen, or the client sends threadId only.

Common situations: Chat UIs that lazily create resources after the first message and poll buffer status too early; body schema not enforcing resourceId in an older client; empty-string resourceId after a failed resource creation.

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/03ca9dee87c26a5f. Report an issue: GitHub.