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
- Pass memory: { resource: '<resourceId>' } in the request body for memory-enabled agents.
- Configure server authentication and implement mapUserToResourceId so the resource ID is derived from the authenticated user.
- If the request should be memoryless, target an agent without memory or omit memory-related options per the current API.
- 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
- Always pass memory: { resource } for memory-enabled agents.
- Configure mapUserToResourceId when server auth is enabled.
- Document the resourceId requirement for all API consumers.
- After server upgrades, re-check memory API changes (implicit fallbacks were removed).
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
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid MemoryRequestContext.resourceId: expected string, go
- Resource ID is required to list threads
- Both threadId or resourceId must be provided
- Agent "${agent.id}" does not have memory configured
- Memory storage is not configured for agent "${agent.id}"
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/e1afe74e7c0473ab.
Report an issue: GitHub.