mastra-ai/mastra · error · HTTPException

A resource ID is required when using memory. Provide memory.

Error message

A resource ID is required when using memory. Provide memory.resource in the request body, or configure server auth with mapUserToResourceId to derive it from the authenticated user.

What it means

When memory is enabled, agent interactions must be scoped to a resource ID (the user/owner of threads). requireEffectiveResourceId throws this 400 when no effective resource ID could be resolved — neither from the request body's memory.resource nor from server auth via a mapUserToResourceId hook. This prevents threads from being created or read without an owner.

Source

Thrown at packages/server/src/server/handlers/utils.ts:92

  requestContext: RequestContext | undefined,
  clientResourceId: string | undefined,
): string | undefined {
  const contextResourceId = requestContext?.get(MASTRA_RESOURCE_ID_KEY) as string | undefined;
  return contextResourceId || clientResourceId;
}

/**
 * Ensures a memory request has a resolvable resource ID. The body's
 * `memory.resource` is optional so authenticated setups can rely on the
 * server-derived resource ID (MASTRA_RESOURCE_ID_KEY set via mapUserToResourceId).
 * When neither the body nor the request context provides one, reject with a
 * clear 400 instead of failing deep inside agent execution.
 */
export function requireEffectiveResourceId(
  effectiveResourceId: string | undefined,
): asserts effectiveResourceId is string {
  if (!effectiveResourceId) {
    throw new HTTPException(400, {
      message:
        'A resource ID is required when using memory. Provide memory.resource in the request body, or configure server auth with mapUserToResourceId to derive it from the authenticated user.',
    });
  }
}

/**
 * Gets the effective threadId, preferring the reserved key from requestContext
 * over client-provided values for security.
 */
export function getEffectiveThreadId(
  requestContext: RequestContext | undefined,
  clientThreadId: string | undefined,
): string | undefined {
  const contextThreadId = requestContext?.get(MASTRA_THREAD_ID_KEY) as string | undefined;
  return contextThreadId || clientThreadId;
}

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Pass memory: { resource: '<resourceId>' } in the request body for memory-enabled agents.
  2. Configure server authentication and implement mapUserToResourceId so the resource ID is derived from the authenticated user.
  3. If the request should be memoryless, target an agent without memory or omit memory-related options per the current API.
  4. After upgrading, update clients that relied on implicit resourceId defaults.

Example fix

// before
await fetch('/api/agents/assistant/stream', { method: 'POST', body: JSON.stringify({ messages }) });
// after
await fetch('/api/agents/assistant/stream', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ messages, memory: { resource: 'user-123' } }),
});
Defensive patterns

Strategy: validation

Validate before calling

function validateMemoryResource(body: { memory?: { resource?: string } }, hasServerAuth: boolean): asserts body is { memory: { resource: string } } {
  const resource = body?.memory?.resource;
  if (!resource && !hasServerAuth) {
    throw new Error('memory.resource is required in the body when the agent uses memory and no mapUserToResourceId is configured');
  }
}

Type guard

function hasEffectiveResource(body: unknown): body is { memory: { resource: string } } {
  const b = body as any;
  return !!b && typeof b.memory?.resource === 'string' && b.memory.resource.length > 0;
}

Try / catch

try {
  const res = await fetch('/api/agents/assistant/stream', { method: 'POST', body: JSON.stringify(payload) });
  if (res.status === 400 && (await res.text()).includes('resource ID is required')) {
    throw new Error('Add memory.resource to the body or configure mapUserToResourceId on the server');
  }
  return res.body;
} catch (e) { throw e; }

Prevention

When it happens

Trigger: Calling generate/stream routes on an agent with memory enabled, where the body has no memory.resource and the server was not configured with authentication providing mapUserToResourceId; also resume/stream-until-idle routes hitting the same check.

Common situations: Local/dev setups with auth disabled (so no user to map) while the agent uses memory; forgetting to pass memory: { resource: 'user-123' } in the request body; a recent server version tightening the old implicit resourceId fallback into this explicit 400.

Understand the failure class

Related errors


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