mastra-ai/mastra · error

sendStateSignal could not load thread ${threadId}

Error message

sendStateSignal could not load thread ${threadId}

What it means

sendStateSignal() throws this when memory.getThreadById({ threadId }) returns null/undefined and no thread exists in the parsed memory request context. The signal needs an existing thread to attach state to; the runtime will not silently create one.

Source

Thrown at packages/core/src/agent/thread-stream-runtime.ts:2721

    target: SendAgentStateSignalOptions<OUTPUT>,
    pubsub?: PubSub,
  ): Promise<SendAgentStateSignalResult<OUTPUT>> {
    if (!target.resourceId || !target.threadId) {
      throw new Error('resourceId and threadId are required to send a state signal');
    }
    const resourceId = target.resourceId;
    const threadId = target.threadId;

    const requestContext = target.ifIdle?.streamOptions?.requestContext;
    const memoryContext = parseMemoryRequestContext(requestContext);
    const memory = await agent.getMemory({ requestContext });
    if (!memory) {
      throw new Error('sendStateSignal requires Mastra memory');
    }

    const loadedThread = (await memory.getThreadById({ threadId })) ?? memoryContext?.thread;
    if (!loadedThread) {
      throw new Error(`sendStateSignal could not load thread ${threadId}`);
    }

    const thread = {
      ...loadedThread,
      id: threadId,
      resourceId: loadedThread.resourceId ?? resourceId,
      createdAt: loadedThread.createdAt ?? new Date(),
      updatedAt: loadedThread.updatedAt ?? new Date(),
      metadata: loadedThread.metadata,
    };

    const applied = await applyStateSignal({
      input: stateInput,
      memory,
      thread,
      resourceId,
      threadId,
      memoryConfig: memoryContext?.memoryConfig,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Create or run the thread once (agent.stream/generate with the same resourceId/threadId) so it persists before sending state signals.
  2. Verify memory.getThreadById({ threadId }) returns the thread with the same storage config the agent uses.
  3. Check that you are connected to the storage backend where the thread actually lives (env-specific DB URLs, table prefixes).

Example fix

// before
await runtime.sendStateSignal(agent, state, { resourceId, threadId: 'thread-1' }); // thread may not exist
// after
if (!(await memory.getThreadById({ threadId }))) {
  await memory.createThread({ resourceId, threadId, title: 'thread' });
}
await runtime.sendStateSignal(agent, state, { resourceId, threadId });
Defensive patterns

Strategy: validation

Validate before calling

const existing = await memory.getThreadById({ threadId });
if (!existing) await memory.createThread({ resourceId, threadId, title: 'auto' });

Type guard

null

Try / catch

try {
  return await runtime.sendStateSignal(agent, state, target);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('sendStateSignal could not load thread')) {
    await memory.createThread({ resourceId: target.resourceId, threadId: target.threadId, title: 'recovered' });
    return runtime.sendStateSignal(agent, state, target);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling sendStateSignal with a threadId that was never created (no prior agent run persisted a thread with that ID), a typo'd/deleted thread ID, or a storage backend that doesn't contain the thread (wrong database/connection).

Common situations: Generating thread IDs client-side without first creating the thread via memory; pointing at a different storage instance in dev vs prod; thread expired/evicted by storage TTL; cross-resource thread ID collision.

Related errors


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