mastra-ai/mastra · error · TripWire
TokenLimiterProcessor: No messages to process. Cannot send L
Error message
TokenLimiterProcessor: No messages to process. Cannot send LLM a request with no messages.
What it means
TokenLimiterProcessor's `processInputStep` fetches all messages from the incoming MessageList and throws a TripWire (with `retry: false`) when there is nothing to process — an LLM request with zero messages is invalid. This guards against sending doomed requests downstream; the TripWire aborts the step rather than silently passing an empty list.
Source
Thrown at packages/core/src/processors/processors/token-limiter.ts:156
/**
* Process input messages at each step of the agentic loop, before they are sent to the LLM.
* Runs at every step (including tool call continuations), preventing the conversation history
* from growing unboundedly during multi-step agent workflows.
*
* System messages are always preserved, and the most recent non-system messages are kept
* within the token budget.
*/
async processInputStep(args: ProcessInputStepArgs): Promise<void> {
const { messageList } = args;
if (!messageList) return;
const messages = messageList.get.all.db();
// If no messages or empty array, throw TripWire - can't send LLM a request with no messages
if (!messages || messages.length === 0) {
throw new TripWire('TokenLimiterProcessor: No messages to process. Cannot send LLM a request with no messages.', {
retry: false,
});
}
// Budget against the full system message set that will reach the model
// (untagged + tagged buckets), not just the untagged view exposed via args.
const allSystemMessages = messageList.getAllSystemMessages();
let systemTokens = 0;
for (const msg of allSystemMessages) {
systemTokens += await this.countCoreSystemMessageTokens(msg);
}
const limit = this.maxTokens;
// If system messages alone exceed the token limit (accounting for conversation overhead),
// throw TripWire - can't send LLM a request with only system messages
if (systemTokens + TokenLimiterProcessor.TOKENS_PER_CONVERSATION >= limit) {
throw new TripWire(View on GitHub (pinned to 75dd419e61)
Solutions
- Ensure at least one user (or system) message exists before invoking the pipeline.
- Guard your caller: skip generation when `messages.length === 0` and return early instead.
- Check whether an upstream processor (filter/redactor) is stripping all messages and adjust its rules.
- Since `retry: false`, do not retry as-is — fix the input, or catch the TripWire and return a friendly 'no input' response.
Example fix
// before await agent.generate(userInput?.trim() ?? ''); // after if (!userInput?.trim()) return 'No input provided'; await agent.generate(userInput);
Defensive patterns
Strategy: try-catch
Validate before calling
const msgs = messageList.get.all.db();
if (!msgs || msgs.length === 0) {
// skip generation entirely instead of running the pipeline
return null;
} Type guard
function hasMessages(list: MessageList | undefined): list is MessageList {
return Boolean(list && list.get.all.db().length > 0);
} Try / catch
try {
result = await agent.generate(input);
} catch (e) {
if (e instanceof TripWire && e.message.includes('No messages to process')) {
result = { text: 'No input provided.' }; // retry: false, so don't retry
} else throw e;
} Prevention
- Guard callers: never invoke generation with empty/whitespace-only input.
- Audit upstream processors for rules that could strip all messages.
- Ensure fresh threads still send at least a system or user message.
- Catch TripWire with retry:false at the edge and convert to a user-friendly response.
When it happens
Trigger: Calling an agent/generation step whose MessageList is empty: no user/system messages were added before the processor ran, all prior processors stripped every message, or a workflow step invokes the pipeline with an empty `messages: []` array.
Common situations: Building message lists dynamically where a filter removed all messages, empty user input passed straight through, memory/storage returning no messages for a fresh thread while the caller sends nothing new, and tests that construct agents without seed messages.
Related errors
- Aborted by processor
- Response body is null
- Response body is null
- execa is not available in Cloudflare Workers
- require(${specifier}) is not available in Cloudflare Workers
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/7ad16d1d9af6a478.
Report an issue: GitHub.