mastra-ai/mastra · error · Error
${errorInfo.message}
Error message
${errorInfo.message} What it means
Inside the generated background-task workflow, when the wrapped task body throws, the workflow records the failure, runs 'failed' completion hooks, publishes a task.failed lifecycle event, deregisters the task context, and re-throws the original error message. This is the propagation of the underlying task's failure, not a manager bug.
Source
Thrown at packages/core/src/background-tasks/workflow.ts:97
const executor =
ctx?.executor ??
(task.agentId ? manager.getStaticExecutor(`${task.agentId}:${task.toolName}`) : undefined) ??
manager.getStaticExecutor(task.toolName);
if (!executor) {
const errorInfo = {
message:
`No executor registered for tool "${task.toolName}". ` +
`Register the tool on Mastra (so workers can resolve it cross-process) ` +
`or run the task in the same process as the producer.`,
};
await storage.updateTask(taskId, { status: 'failed', error: errorInfo, completedAt: new Date() });
const failedTask = await storage.getTask(taskId);
if (failedTask) {
await manager.runLocalCompletionHooks(failedTask, 'failed', { error: errorInfo });
await manager.publishLifecycleEvent('task.failed', failedTask);
}
manager.deregisterTaskContext(taskId);
throw new Error(errorInfo.message);
}
// Throttled progress publisher.
const progressThrottleMs = manager.config.progressThrottleMs;
const shouldThrottleProgress =
typeof progressThrottleMs === 'number' && Number.isFinite(progressThrottleMs) && progressThrottleMs > 0;
let lastProgressEmitMs: number | undefined;
const onProgress = async (chunk: any) => {
if (shouldThrottleProgress) {
const now = Date.now();
if (lastProgressEmitMs !== undefined && now - lastProgressEmitMs < progressThrottleMs) return;
lastProgressEmitMs = now;
}
await manager.publishLifecycleEvent('task.output', { ...task, chunk });
};
const abortController = new AbortController();
if (!manager.registerActiveAbortController(taskId, abortController)) {View on GitHub (pinned to 75dd419e61)
Solutions
- Inspect the errorInfo.message (and the task record's failure details in storage) to find the root cause thrown by your task body.
- Add try/catch inside the task body for recoverable failures and return a structured result instead of throwing.
- Subscribe to the task.failed lifecycle event / completion hooks to log full error details.
- Fix the underlying fault (invalid input, missing credentials, upstream API outage) indicated by the message.
Example fix
// before
await manager.workflow(async ({ data }) => {
return await callModel(data.prompt); // rejects -> task.failed -> rethrown
});
// after
await manager.workflow(async ({ data }) => {
try {
return await callModel(data.prompt);
} catch (err) {
logger.error('task body failed', err);
throw new Error(`Model call failed: ${err.message}`); // clearer root cause
}
}); Defensive patterns
Strategy: try-catch
Validate before calling
function validateTaskInput(input, schema) {
const result = schema.safeParse(input);
if (!result.success) throw new Error(`Invalid task input: ${result.error.message}`);
return result.data;
}
// validate BEFORE starting the workflow so failures don't surface mid-run Try / catch
try {
await manager.workflow(taskBody, { /* ... */ });
} catch (e) {
logger.error('Background task failed', { message: e.message, taskId });
// inspect the failed task record + runLocalCompletionHooks data for root cause
await alerting.notifyTaskFailure(taskId, e.message);
} Prevention
- Wrap the task body's fallible I/O (model calls, HTTP) in try/catch with logging.
- Validate task inputs before starting the task, not inside it.
- Register completion hooks and subscribe to task.failed to capture full error context.
- Add retries with backoff around transient upstream calls inside the task body.
When it happens
Trigger: Any uncaught exception thrown inside the function wrapped by manager.workflow()/buildBackgroundTaskWorkflow — the errorInfo comes from the failed task body, e.g. an LLM call failure, validation error, or unhandled rejection in the task handler.
Common situations: A task's model API call fails (rate limit, auth), the task body dereferences undefined data, or an awaited sub-operation rejects — surfacing via the workflow run as this re-thrown error.
Related errors
- res.error.message
- Workflow ${workflowId} not found
- Workflow ID is required
- Failed to stream workflow: ${response.statusText}
- Response body is null
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/34f8970fbfbf4731.
Report an issue: GitHub.