October 1, 2026
Highlights
Default Agent Error Recovery (Repair-first + Safe Retries)
Agents now automatically recover from common provider failures with three default error processors (ProviderHistoryCompat, PrefillErrorHandler, StreamErrorRetryProcessor) enabled by default, repairing history/prompt before retrying. You can still fully control or disable defaults via errorProcessors and errorProcessorDefaults: false.
Better Tool-Pause UX: New tool-call-resumed Stream Chunk
Streaming now emits a tool-call-resumed chunk when a suspended or approval-gated tool call resumes (durable and non-durable), allowing clients to reliably mark questions/approvals as answered before the tool-result arrives. The change is wired through @mastra/ai-sdk and @mastra/react (useChat) so UIs can clear pending tool states correctly.
Google Workspace Toolsets + Binary Proxy Responses in @mastra/connect
@mastra/connect adds Google Docs/Drive/Sheets toolsets (edit/export docs, manage Drive files/permissions, read/write Sheets) for agents running through Mastra Cloud. The platform proxy now supports binary responses via responseType: 'arraybuffer', unlocking document exports and other binary-download actions.
Observational Memory Can Show Attachments to the Model
@mastra/memory adds viewAttachment to the observational memory recall tool so models can see the actual attachment (native media parts for images/PDFs) instead of only a description. Attachment references in recall results are also fixed so agents can correctly reuse prior files/images.
Reliability & Scale Fixes for Durable/Evented Execution
Durable agents and evented workflows get multiple correctness fixes: output-processor retries now work for durable runs, resumed tool calls can run in parallel again, and long-running evented steps no longer double-run due to redelivery (heartbeat + lease fencing). Large thread history loading is also improved from quadratic to linear time, dramatically reducing latency on big threads.
Breaking Changes
- Durable streams no longer emit a separate
tripwirechunk when an output processor blocks; usefinishReason === 'tripwire'andoutput.tripwireinstead.
Changelog
@mastra/core@1.73.0
Minor Changes
-
Every agent now recovers from transient provider failures, assistant-prefill rejections, and provider history incompatibilities with no configuration. Three error processors —
ProviderHistoryCompat,PrefillErrorHandler, andStreamErrorRetryProcessor— are on by default, in the order that repairs history before anything retries. AProviderHistoryCompatinerrorProcessorsnow also repairs the outbound prompt before the provider sees it, instead of only reacting to a rejection. (#24473)You stay in control of the list:
// Replace one default: your instance with the same id takes its slot. // Retries above 3 also need maxProcessorRetries. new Agent({ ..., errorProcessors: [new StreamErrorRetryProcessor({ maxRetries: 5 })], maxProcessorRetries: 5 }) // Run only your own processors — none of the defaults are merged in. new Agent({ ..., errorProcessors: [myProcessor], errorProcessorDefaults: false }) // Run with no error processors at all. new Agent({ ..., errorProcessorDefaults: false })
errorProcessorDefaults: falseis the only opt-out: an emptyerrorProcessorslist merges like any other and still gets the defaults.The default retry processor retries transient failures only. Transient failures recover through provider
isRetryablemetadata, the built-in OpenAI stream-error matcher, or the connection-reset matcher, while deterministic failures — a rejected structured-output attempt, a validation error, or any HTTP 400 the repair processors cannot fix — surface immediately instead of being replayed unchanged. PassStreamErrorRetryProcessor({ retryUnknownErrors: true })inerrorProcessorsto retry unmatched errors.createCodingAgentkeeps its shipped behavior, retrying both unmatched errors and bad-request responses, as it always has.Error-processor retries are bounded by a safety cap of
3per turn when you don't setmaxProcessorRetries; the defaults stop well below it on their own. The "errorProcessors are configured without an explicit maxProcessorRetries" warning now fires only when you configured error processors yourself, not for the framework defaults. -
Export
findGatewayForModelandgetGatewayIdfrom@mastra/core/llmso callers can check which registered gateway the model router would pick for a model ID. Like the router,findGatewayForModelskips disabled gateways. (#25482)import { findGatewayForModel, getGatewayId } from '@mastra/core/llm'; const gateway = findGatewayForModel('acme/fast-1', Object.values(mastra.listGateways() ?? {})); console.log(getGatewayId(gateway));
-
Added a
tool-call-resumedstream chunk. It is emitted when a suspended or approval-gated tool call resumes, on both regular and durable agents, and comes before that call'stool-result.payload.kindtells you whether it was a suspension or an approval. Clients can now tell that a suspension was answered even when a sub-agent suspended through a delegation call and the delegation's later result replaces the tool output. Fixes #24280. (#25491)const stream = await agent.resumeStream({ answer: 'yes' }, { runId, toolCallId }); for await (const chunk of stream.fullStream) { if (chunk.type === 'tool-call-resumed') { markAnswered(chunk.payload.toolCallId); } }
-
Invalid tool-call IDs on Anthropic models are now rewritten in the outbound request, so they no longer reach Anthropic and no longer require a failed call to recover. Persisted history keeps its original IDs. The rule's reactive repair (
errorPatternsandfix) stays as the fallback for Claude served through a provider the preemptive check doesn't recognize, such as Vertex-hosted Claude, and for placements outside the agent's prompt path. (#24505) -
Added an optional
resolveSubagentModel(modelId, { requestContext })option toAgentControllerConfig. Subagent models can now resolve with the calling run's request context, so custom providers and tenant credentials work for subagents the same way they do for the main agent. The context passed in doesn't include the parent run's thread or resource IDs. (#25482)const controller = new AgentController({ // ... resolveSubagentModel: (modelId, { requestContext }) => resolveTenantModel(modelId, requestContext), });
Patch Changes
-
Fixed aborting an agent run taking up to 10 seconds when the provider reported low remaining rate-limit tokens. The pause between steps now ends as soon as the run's
abortSignalfires. (#25648) -
Update provider registry and model documentation with latest models and providers (
42b8761) -
Fixed trace aggregation returning a server error when a
havingfilter usedincludesornotIncludes. These operators are now rejected with a validation error. (#25607) -
Fixed saving builder workflows with classifier steps when the model sends
nullformaxRetriesorproviderOptions. These values are now treated as omitted, the same asretriesandmetadata, instead of failing validation. (#25531) -
Fixed startAsync so it returns only after workflow execution is durably recoverable. Fixes #24585. (#24673)
-
Fixed misleading tool input validation errors. When a model sent
nullfor optional fields and the call still failed for another reason, the error listed thenullfields as problems and hid the real cause. Errors now report only the issues that remain afternullvalues are removed, so models can fix the actual problem on the next attempt. (#25656) -
Fixed agent controller sessions losing the signed-in user when memory is configured as a function. Cloning a thread, forking a subagent, and opening a thread's history subscription (opening a session, switching or creating a thread, sending a message or notification, resuming a suspended tool) now pass the caller's request context to the memory factory. If the session already has the thread open, the open subscription is reused and its history keeps the memory it resolved when it opened. Per-user memory now resolves correctly instead of failing with a missing user context. (#25082)
Pass the caller's context when cloning, switching, or creating a thread:
await session.thread.clone({ sourceThreadId, requestContext }); await session.thread.switch({ threadId, requestContext }); await session.thread.create({ title, requestContext }); await session.thread.delete({ threadId, requestContext });
Deleting a thread also removes it from the caller's resolved memory, so a cloned thread's messages are not left behind.
A message sent while a run is active joins that run and uses the memory resolved for the caller who started it. The next run resolves memory with the context of the caller whose message starts it.
Also in: @mastra/server@1.73.0
-
Fixed durable agents stopping when an output processor asks for a retry.
abort(reason, { retry: true })inprocessOutputStepnow calls the model again with the reason as feedback, up tomaxProcessorRetries(set on the agent or per call), like regular agents do. (#25585)Fixed durable agent streams ending early when an output processor blocks a response. The stream now ends with a
finishchunk,finishReasonis'tripwire',onFinishis called, andoutput.tripwireholds the reason. Durable streams no longer emit a separatetripwirechunk for this case, matching regular agents. See #22980.Migrating from the
tripwirechunkIf you listened for the
tripwirechunk on a durable stream, readfinishReasonandoutput.tripwireinstead:// Before for await (const chunk of output.fullStream) { if (chunk.type === 'tripwire') console.log(chunk.payload.reason); } // After for await (const chunk of output.fullStream) { // render chunks as usual } if ((await output.finishReason) === 'tripwire') { console.log(output.tripwire?.reason); }
-
Fixed durable agents reporting
retryCount: 0to processor hooks after an API-error retry. Hooks likeprocessInputStep,processLLMRequestandprocessOutputStepnow see the same retry count as with a regularAgent. (#25642) -
Fixed long-running evented workflow steps running twice when the broker redelivers the step event before the step finishes. Workers now send a heartbeat while a step runs, so the broker does not hand the event to another worker. Each step run is also fenced with a lease, so a redelivered copy is dropped while the original is still running. Redis Streams and Valkey Streams support the heartbeat. Steps should still be idempotent, because a worker crash can still cause a step to run again. (#24769)
Also in: @mastra/redis-streams@0.6.1, @mastra/valkey-streams@0.5.3
-
Fixed
run.timeTravel()rejecting arrayinputDatawhen targeting a top-level.foreach()step. Each array element is now validated against the step's input schema, so Studio's "Run next step" works at foreach loops, including for Inngest workflows. (#25626)Also in: @mastra/inngest@1.10.2
-
Fixed durable agents running output processors twice on tool results. A
processOutputStreamprocessor now sees each tool result, tool error, and denied tool call once, so counters, billing, and edits to tool results are no longer applied twice. Fixes part of #22980. (#25578) -
Use Web Crypto for portable identifiers, random secrets, and asynchronous sandbox profile hashing (#25462)
-
Fixed slow loading of long conversation histories. Loading stored messages took time that grew with the square of the thread length, so a thread with 10,000 messages could block the server for several seconds on every load. Loading now grows linearly with the thread length. Fixes #24143. (#25061)
-
Tool approval and tool suspension requests now report whether they were actually accepted. Previously,
approveTool()andrespondToToolSuspension()always returned success, even when the decision was stale, a duplicate, or answered a question that was no longer pending. They now resolve to{ ok: false, reason }in those cases, so you can tell an accepted decision from one that was ignored. (#25087)const ack = await session.approveTool(toolCallId, true); if (!ack.ok) console.warn(`Approval not applied: ${ack.reason}`);
approveTool()andrespondToToolSuspension()no longer retry automatically. A retried decision would be rejected as already handled, so an applied decision could be reported as ignored.Also in: @mastra/client-js@1.51.1, @mastra/server@1.73.0
-
Fixed evented workflows so concurrent resume calls continue a suspension only once. (#25458)
-
Fixed
DurableAgentconstruction to preserve dynamic model resolution until request context is available. Wrapping an agent with a request-dependent model no longer resolves the model eagerly during startup. (#25359) -
Reduced durable agent snapshot size by no longer saving the agent's system prompt on every step. Resume, tool approval, and trace rebuilds still use the copy kept in the run input, so behavior and traces are unchanged. (#25609)
-
Include
threadIdandresourceIdon lightweight trace list rows so the Thread ID and Resource ID columns render when the trace query API is unavailable. (#25433)Also in: @mastra/clickhouse@1.22.1, @mastra/client-js@1.51.1, @mastra/duckdb@1.12.1, @mastra/playground-ui@60.1.0
-
Fixed filesystem storage writing MCP client config fields like
nameandserversonto the client record duringupdate(). Only record-level fields are stored there now; config stays in versions. (#25646) -
Fixed durable agents rebuilding a run on another worker, or after a restart, with the wrong request processors. The rebuilt run now uses the processors configured on the wrapped agent, so processors that rewrite the outbound model request keep running, and a per-call
errorProcessors: []still turns error processors off. (#24473) -
Fixed evented workflow restarts that occur before the first step is saved. (#25389)
-
Fixed a follow-up message sent right after aborting a run replaying the aborted run. A new thread subscription no longer re-emits the aborted run's lifecycle events (such as a second
agent_start) while that run is still shutting down. (#25641) -
Fixed
run.cancel()overwriting the status of a workflow run that had already finished. Canceling a run that ended assuccess,failed,canceled,tripwireorbailedis now a no-op, so its stored status is preserved. This applies to both the default and evented workflow engines, and to thePOST /api/workflows/:workflowId/runs/:runId/cancelroute. (#25414) (#25628) -
Fixed
stream.textand the last step'stextresolving to an empty string when an agent has an output processor and the run stops viastopWhenon a step that contains both text and a tool call. Output processors that intentionally clear text still work as before. (#25381) -
Fixed
ToolCallFilterstripping a resumed run's own tool calls. When a tool suspended the agent (for exampleaskUserTool) and the run was continued withresumeStream(), the filter treated the suspended tool call and its result as prior history and removed them from the model prompt. The model never saw its question or the user's answer, so it asked again and the run suspended forever. Tool calls made in the current run, including everything before a suspension, now stay in the prompt after resume. Fixes #24382 (#25566) -
Fixed
resumeStreamrunning resumed tool calls one at a time undertoolCallConcurrency: { strategy: 'called' }. Parallel-safe tool calls that paused together, such as sub-agent delegations, now resume in parallel. If one call pauses again, its siblings still continue. (#25490) -
Fixed background workflow tools filling Redis with oversized progress updates (#25590). When a background workflow step called an agent, each progress update carried a full copy of the model request and message history, so a single update could reach 60MB. Progress updates now leave those copies out and no longer repeat the task's arguments, while progress information such as text, finish reason, and usage is still delivered. (#25606)
-
Fixed durable agents dropping custom
resumeDataon tool approval. When a caller approves a tool call with extra keys, for examplesendToolApproval({ approved: true, resumeData: { approved: true, note: 'hello' } }), the durable agent now forwards that payload to the tool'sexecutethroughcontext.agent.resumeData, matching the non-durable agent. A bare{ approved: true }is still not forwarded. Fixes #24561 (#25562) -
Fixed
LocalSandboxseeding a working directory with a mix of two checkpoint versions whensnapshot()replaced the checkpoint duringstart(). The seed now retries until it copies one complete checkpoint. (#25528) -
Fixed tool request context validation accepting invalid values when
requestContextSchemais a Valibot schema. Valibot returns both a value and issues on failure, and the issues are now reported instead of being ignored. (#25644) -
Fixed goals using up a run when the goal judge errors. A failed judge call (for example, a dropped network connection) still pauses the goal so it can be resumed, but the failed attempt no longer counts against the goal's run limit. Fixes #22446. (#25205)
@mastra/acp@0.4.2
Patch Changes
-
Generate SDK, pubsub, and workflow identifiers with Web Crypto while preserving synchronous behavior. (#25462)
Also in: @mastra/claude@0.3.2, @mastra/cursor@0.3.2, @mastra/inngest@1.10.2, @mastra/openai@1.1.2, @mastra/redis-streams@0.6.1, @mastra/valkey-streams@0.5.3
@mastra/agentcore@0.5.1
Patch Changes
-
Generate workspace, integration, channel, and voice identifiers with Web Crypto without changing synchronous APIs. (#25462)
Also in: @mastra/cloudflare-sandbox@0.5.1, @mastra/daytona@0.11.2, @mastra/discord@1.2.1, @mastra/docker@0.9.2, @mastra/livekit@0.4.2, @mastra/nestjs@0.2.32, @mastra/voice-aws-nova-sonic@0.2.3, @mastra/voice-google-gemini-live@0.14.13
@mastra/ai-sdk@1.10.6
Patch Changes
-
Mapped the new
tool-call-resumedchunk to adata-tool-call-suspendedpart (ordata-tool-call-approvalpart for approvals) withresumed: trueand the same id. The part keeps the original suspend payload, args, and resume schema, so UIs mark the question as answered in place without losing it. (#25491)for (const part of message.parts) { if (part.type === 'data-tool-call-suspended' && part.data.resumed) { // The question in part.data.suspendPayload has been answered } }
-
Custom
data-*chunks written withtransient: truenow keep that flag when streamed through@mastra/ai-sdk, so they reachonDatawithout being saved intomessage.parts. (#25608)
@mastra/auth-studio@1.3.8
Patch Changes
- Fixed local dev auth: MastraAuthStudio now falls back to organizationId in .mastra-project.json when neither the constructor option nor MASTRA_ORGANIZATION_ID env var is set. Running pnpm mastra dev in a project linked to a platform organization now pins AuthKit to that org and skips the WorkOS org picker for multi-org users, without requiring the env var to be exported locally. (#25583)
@mastra/clickhouse@1.22.1
Patch Changes
-
Fixed ClickHouse feedback and score aggregates returning a sum when
count_distinctwas requested. They now return the number of distinct values. (#25615) -
Fixed ClickHouse score aggregates returning 0 instead of null when no scores match the filter, matching the other storage adapters. (#25607)
-
Read the results of the serial-cursor probe and counter warm-up queries in the observability store, so their connections are freed at once instead of staying busy until the client's request timeout. This removes waits of up to 30 seconds after
init(). (#25613) -
Generate storage identifiers with Web Crypto without changing synchronous storage interfaces. (#25462)
Also in: @mastra/elasticsearch@1.4.3, @mastra/libsql@1.24.1, @mastra/mongodb@1.20.1, @mastra/mssql@1.10.1, @mastra/mysql@0.11.1, @mastra/oracledb@0.4.2, @mastra/pg@1.28.1, @mastra/redis@1.4.8, @mastra/spanner@1.9.1, @mastra/upstash@1.5.1, @mastra/valkey@0.2.4
@mastra/client-js@1.51.1
Patch Changes
-
Fixed Studio hiding processors that only implement
processLLMRequest, such asToolCallFilter. The processors API now reports anllmRequestphase for these processors, so they appear in the Processors page, sidebar, and picker. Studio disables direct execution of this phase because it operates on the provider prompt during an agent call. Direct API requests return a 400 error. (#25500)For example,
GET /api/processorscan return:{ "tool-call-filter": { "id": "tool-call-filter", "phases": ["llmRequest"], "agentIds": ["my-agent"], "configurations": [{ "agentId": "my-agent", "type": "input" }], "isWorkflow": false } }Also in: @mastra/server@1.73.0
@mastra/code-sdk@1.10.0
Minor Changes
-
Added an opt-in experimental agent runtime for validating Mastra Code on durable and evented execution. (#25359)
Before
mastracode
Mastra Code always used the standard coding agent.
After
MASTRACODE_EXPERIMENTAL_AGENT=durable mastracode MASTRACODE_EXPERIMENTAL_AGENT=evented mastracode
The SDK now wraps the coding agent with the requested implementation, rejects invalid or unsupported configurations at startup, and reports the resolved workflow engine.
Patch Changes
-
Mastra Code now uses the shared error recovery defaults from
@mastra/core. It still repairs rejected message history and assistant-prefill errors before it retries, and it keeps its own tuned retry settings for network and server errors. (#24473) -
Subagents now resolve models the same way the main agent does, including custom providers and tenant credentials from the calling run. Model IDs owned by another registered gateway still go to that gateway. (#25482)
Behavior change for Factory: tenant subagents no longer fall back to the server's environment API keys (such as
ANTHROPIC_API_KEY). A subagent whose provider isn't connected for the signed-in account now fails with a missing-credential error, matching the main agent. Connect the provider or add an org credential for those accounts. -
Fixed account switching and removal across multiple running Mastra Code instances. Each instance now uses the latest accounts, including in
/login. (#25517)- Requests using automatic account routing retry on a remaining account when another instance removes the account they were using.
- Requests routed to a specific account stop instead of switching to a different account when that account is removed. Applying that account no longer shows a notice on every prompt, but failover notices still appear.
-
Generate Factory, CLI, channel, and signal identifiers with Web Crypto while retaining synchronous interfaces. (#25462)
Also in: @mastra/factory@0.19.0, @mastra/github-signals@0.5.1, @mastra/slack@1.7.1, @mastra/telegram@0.2.1
-
Fixed headless runs without thread options to start a fresh thread instead of reusing the current thread. (#25594)
@mastra/codemod@1.1.6
Patch Changes
- Fixed the
v1/agent-abort-signalcodemod creating a duplicateabortSignalkey when the call already had one at the top level. It now leaves those calls unchanged and asks you to resolve them manually. (#25617)
@mastra/connect@0.6.0
Minor Changes
-
Added Google Docs, Google Drive, and Google Sheets toolsets to @mastra/connect. Agents connected through Mastra Cloud can now edit Google Docs (including PDF/DOCX/HTML/text export), manage Google Drive files, folders, permissions, and shared drives, and read and write Google Sheets, alongside the existing Gmail and Google Calendar toolsets. (#25596)
Added binary response support to the platform proxy. Tool templates that need to fetch binary payloads (file exports, image downloads) can now pass
responseType: 'arraybuffer'on a proxy request; the response body is returned as anArrayBufferinstead of being parsed as JSON. This unlocks document-export tools such as Google Docs'export-document, and any future providers that ship binary-download actions.
Patch Changes
- Provider errors that nest their message as
{ "error": { "message": "..." } }(for example OpenAI) now include that message in the thrown error. A missing OpenAI batch now reportsProvider request failed (404): No such batch: batch_abc123instead ofProvider request failed (404).(#25533)
@mastra/convex@1.6.1
Patch Changes
updateWorkflowStatenow resolves toundefinedwhen the workflow run has no saved snapshot, matching the other storage adapters. It previously threwWorkflow snapshot not found for runId …, which could surface as an unhandled error during a workflow resume. (#25534)
@mastra/daytona@0.11.2
Patch Changes
- Fixed S3 mounts in Daytona sandboxes for buckets outside
us-east-1and for prefixes without a placeholder object. The s3fs mount now passes the configured region for request signing and enablescompat_dirwhen aprefixis set. (#25600)
@mastra/deployer@1.73.0
Patch Changes
-
Generate server request and development identifiers with Web Crypto (#25462)
-
Improved deployer builds to apply internal module replacements consistently during dependency analysis and bundling. (#25573)
-
Fixed Bun workspace builds when packed dependencies conflict with source lockfiles (#24879). (#25575)
@mastra/deployer-sandbox@0.3.17
Patch Changes
- Use Web Crypto to compute asynchronous install-input digests without changing the cache key. (#25462)
@mastra/docker@0.9.2
Patch Changes
- Fixed
DockerSandboxreporting its default image instead of the running container's image after reconnecting, in bothgetInfo()and the agent instructions. (#25622)
@mastra/e2b@0.12.3
Patch Changes
-
Fixed S3 mounts ignoring
sessionToken, so temporary AWS credentials (for example from STS AssumeRole) now work. Previously only permanent access keys could mount a bucket. (#25563) (#25599) -
Generate code-mode temporary file suffixes with Web Crypto. (#25462)
@mastra/editor@0.15.5
Patch Changes
-
Fixed
editor.scorer.clearCache()leaving stored scorers registered on Mastra after they were loaded with a specific version (getById(id, { versionId })or{ versionNumber }). Clearing the whole cache now unregisters them, so a later defaultgetByIdregisters the latest scorer instead of staying stuck on the historical one. (#25544) -
Builder agents keep their stability error processors on every supported
@mastra/coreversion, including cores that predate the framework defaults. Adding a processor never costs the builder its recovery: (#24473)createBuilderAgent({ errorProcessors: [myProcessor] }); // resolved: provider-history-compat, prefill-error-handler, // stream-error-retry-processor, myProcessor
A caller's array merges with the builder's list, which runs in repair-first order. A caller instance with a default's
idtakes that default's slot. Other caller processors run after the defaults. An empty array keeps the defaults.errorProcessorDefaults: falseopts out and runs the caller's list as given. A function-valued override passes through unchanged, so a callback must return every processor it needs.DEFAULT_BUILDER_ERROR_PROCESSORSis still exported.
@mastra/elysia@0.1.13
Patch Changes
-
Fixed
createAuthMiddlewarereturning 401 for custom API routes registered withrequiresAuth: false. When the helper was mounted on a path that also served a public custom route (for exampleapp.use('*', createAuthMiddleware({ mastra }))), it re-marked that route as protected. Public routes, including pattern routes such as/webhooks/:id, now stay public without also being listed inauthConfig.public. (#25560)Also in: @mastra/express@1.5.17, @mastra/fastify@1.5.17, @mastra/hono@1.7.15, @mastra/koa@1.7.17
@mastra/evals@1.10.5
Patch Changes
- Fixed checks.matches scoring matching outputs as 0 when the pattern uses the g or y flag and the scorer runs over several items. (#25633)
@mastra/factory@0.19.0
Minor Changes
-
Added support for replacing the built-in Work and Review boards. Set
includeDefaultBoards: falseand install your own board with idworkorreview. A same-id board still errors while the built-ins are installed. Closes #23881. (#25595)new MastraFactory({ storage, includeDefaultBoards: false, boards: [myWorkBoard], });
Patch Changes
-
Fixed retrying a failed Factory run after its work item moved to another phase. The retry is now refused (
canRetry: falseand a 409decision_not_retryable), and a stale run already in the queue settles as superseded instead of starting a session for the old role and reporting success. (#25550) -
Fixed the GitHub issues and pull request lists returning a 502
github_fetch_failederror when re-ingesting the listed items into Factory rules failed. The lists now load and the ingestion failure is logged. (#25663) -
Fixed Factory reviews posting a verdict that contradicts their review text. (#25494)
- The source-control review tool, which GitLab reviews use, now rejects a review whose
Verdict:line does not match the approve or request-changes choice. It also rejects a review whoseReviewed head:is not the current merge request head. - GitHub review skills now write each review body to a file named after the reviewed commit. Before posting, they check the verdict line and reviewed head, and they delete the file afterwards. A review written for an earlier commit is no longer reposted on a newer one.
- The source-control review tool, which GitLab reviews use, now rejects a review whose
-
Fixed the Jira integration returning a generic 404 error, instead of the friendly not-found message, when commenting on a missing issue by key (e.g.
ENG-404). (#25623) -
Fixed an internal reconciliation timestamp (
externalSourceMissingAt) leaking into work item metadata returned by the Factory API. (#25607) -
Improved the option pickers in Factory settings (notifications, tool permissions, observe attachments) and the API key sharing choice. They now use one consistent segmented control with a sliding selection. Changing a tool permission now updates instantly instead of briefly disabling the control while it saves. If saving fails, the previous choice is restored and an error is shown. (#25570)
-
Fixed web OAuth device sign-in (GitHub Copilot, OpenAI Codex) telling a second concurrent poll to wait for the entire remaining sign-in window. It now retries after 250 ms while another poll is in progress. (#25527)
-
Factory now dismisses its own stale change requests when it approves a pull request. Previously, if an earlier Factory review requested changes and a later Factory review (from a different reviewer identity) approved the repaired PR, GitHub kept the PR blocked at "changes requested". Only change requests left by the Factory GitHub App before the approval are dismissed; human reviews are never touched. (#25610)
@mastra/google-drive@0.2.2
Patch Changes
- Sign PKCS#8 Google Drive service-account JWTs with Web Crypto while preserving PKCS#1 key support. (#25462)
@mastra/inngest@1.10.2
Patch Changes
-
Fixed Studio's Approve and Decline buttons for Inngest agents.
sendToolApproval()now resumes the suspended run on Inngest instead of failing with "could not find a suspended run". (#25557) -
Fixed nested Inngest workflow and durable agent failures losing their error message. Callers now receive the real cause (for example
step output size is greater than the limit) instead of{"stepId":"…","name":"Error"}. (#25598)
@mastra/libsql@1.24.1
Patch Changes
- Fixed
updateWorkflowStatein the LibSQL store not updating the run'supdatedAt, so updated runs looked stale in sorting and retention. (#25618)
@mastra/loggers@1.3.4
Patch Changes
- Fixed FileTransport log queries returning no logs when the log file contains a malformed line. Malformed lines are now skipped and valid logs are still returned. (#25624)
@mastra/mcp@2.1.2
Patch Changes
- Generate MCP continuation keys with Web Crypto (#25462)
@mastra/memory@1.34.0
Minor Changes
-
Added
viewAttachmentto the observational memoryrecalltool. Passing it withcursorandpartIndexshows the attachment itself to the model instead of only describing it. Inline data such as base64 or data URIs is sent as a native media part. Attachments stored as remote URLs or provider file IDs, media types outsideimage/*andapplication/pdf, and payloads over 10 MiB come back as an explanation instead. (#25054)recall({ mode: 'messages', cursor: 'msg_123', partIndex: 0, viewAttachment: true });
Patch Changes
-
Generate observational-memory identifiers and digests with Web Crypto (#25462)
-
Fixed the observational memory
recalltool dropping attachment references. Image and file parts now include their media type and the stored URL or provider file ID instead of only the filename, so agents can reuse an earlier attachment. Inline data such as base64 or data URIs is never printed, including media stored in earlier tool results. Fixes #23813. (#25054)
@mastra/modal@0.7.1
Patch Changes
-
Fixed ModalFilesystem copyFile and moveFile deleting the source when the destination is the same path. They now throw FileExistsError and leave the file untouched. (#25634)
-
Fixed
ModalSandbox.clone()ignoring theworkingDirectoryoverride, so clones now use the requested directory instead of the template's. (#25607)
@mastra/mongodb@1.20.1
Patch Changes
- Fixed
documentFilterwith operators like$regexfailing on MongoDB Atlas vector queries. Filters that$vectorSearchcan't evaluate now run as a pre-filter instead of being sent inside$vectorSearch.filter. (#25647)
@mastra/mysql@0.11.1
Patch Changes
- Fixed
putManyon the MySQL blob store overwriting existing blobs. Blobs whose hash is already stored are now skipped, matchingputand the other storage adapters, so a blob keeps thecreatedAtof when it was first stored instead of being moved forward on every skill republish. (#25543)
@mastra/observability@1.18.3
Patch Changes
-
Fixed missing cost estimates for the newest models, such as OpenAI
gpt-6-lunaandgpt-6-sol, and Anthropicclaude-opus-5-5andclaude-sonnet-5-5. The pricing data is now up to date. (#25559) -
Fixed recorded traces choosing the wrong root span when a storage backend returns spans out of start order (for example ClickHouse or DuckDB) and the trace contains a span whose parent was never persisted. Scores and feedback added to these traces now carry the real root's entity and tags. (#25536)
-
Fixed provider API errors on traces showing only a message like "Service Unavailable". Span errors now include the HTTP status code, request URL, retryability and provider response body under
details, so you can see what failed and where. (#25407)
@mastra/pg@1.28.1
Patch Changes
-
Fixed Postgres skill updates not advancing
updatedAtwhen the update only re-sends unchanged skill content. Postgres now bumpsupdatedAton every update, matching the in-memory and LibSQL stores, so PATCH responses andupdatedAt-sorted skill lists stay consistent across stores. (#25537) -
Fixed
PgVector.query()with a filter only andincludeVector: trueonbitandsparsevecindexes. It threw aSyntaxErroror returned a single number; it now returns the stored embedding as anumber[], the same as vector-similarity queries. (#25561) -
Fixed Postgres workflow definitions returning their creation time as
updatedAtafter an edit. (#25658) -
Fixed Postgres workspace updates not advancing
updatedAtwhen the update only re-sends unchanged workspace configuration. Postgres now bumpsupdatedAton every update, matching the in-memory and LibSQL stores. (#25539)
@mastra/playground-ui@60.1.0
Minor Changes
-
Added
SegmentedControl, a pill-shaped control for picking one of a few options. The selected option is marked by a thumb that slides between segments. Items can hold text, an icon and text, or only an icon (iconOnly). It supports thesm/md/lgcontrol sizes, and disabled options with an optional tooltip. (#25570)import { SegmentedControl, SegmentedControlItem } from '@mastra/playground-ui/components/SegmentedControl'; <SegmentedControl aria-label="Permission" value={policy} onValueChange={setPolicy}> <SegmentedControlItem value="allow">Allow</SegmentedControlItem> <SegmentedControlItem value="ask">Ask</SegmentedControlItem> <SegmentedControlItem value="deny">Deny</SegmentedControlItem> </SegmentedControl>;
ThemeToggleis now built onSegmentedControl, so both look the same. It uses the shared control sizes, so the default size is slightly taller and lines up with buttons and selects.size="xs"is deprecated and renders assm. Keyboard focus is now visible. -
Improved warning and error colors so alerts, status dots, badges, buttons, charts, and usage values read as one family in light and dark mode. (#25587)
- The
yellowramp is nowamber. It warms as it darkens, so warnings read as gold instead of mustard or olive. - Red uses one hue across every step, so error text, badges, charts, and destructive buttons match.
- Added
--warning-foregroundand--destructive-foregroundfor colored text and icons.*-indicatoris the fill for dots, bars, chart marks, and borders. The warning fill is too light to read as text in light mode, so text needs its own token. - Dark-mode red surfaces (alerts, red badges, error washes) use a clear red instead of a brownish maroon, with a softer border.
- Destructive and warning badges use the same text color as the values beside them.
- Badge fills are translucent tints, so a badge follows the card or row under it on hover instead of sitting on it as a solid patch. On a resting surface they look the same as before. Product avatars stay solid.
- The disabled destructive button uses a softer fill with muted text, so it no longer looks like an enabled button in a darker red.
Removed
Removed Replacement --yellow-50…--yellow-950and*-yellow-*utilities--amber-*,*-amber-*--yellow-soft-*and*-yellow-soft-*utilities--amber-soft-*,*-amber-soft-*--badge-yellow-strong,-subtle,-edge,-indicator,-foreground--badge-amber-*--chart-yellow--chart-amberBadge variant="yellow"variant="amber"'yellow'incategoricalHuesandCategoricalHue'amber'yellow-*,yellow-soft-*,badge-yellow-*, andchart-yellowkeys inColorsfrom@mastra/playground-ui/tokensThe matching amberkeystext-warning-indicatorandtext-destructive-indicatorfor text and icons (the tokens remain for fills)text-warning-foreground,text-destructive-foreground--color-brand-yellowis part of the fixed Mastra palette and is unchanged.// Before <Badge variant="yellow">Pinned</Badge> <span className="text-warning-indicator">870K</span> <i className="bg-badge-yellow-indicator" /> // After <Badge variant="amber">Pinned</Badge> <span className="text-warning-foreground">870K</span> <i className="bg-badge-amber-indicator" />
- The
Patch Changes
-
Fixed pasting a single KEY=value line into an environment variable value field importing it as a new row instead of keeping it as the value. (#25640)
-
Fixed the thread view of a trace: resumed runs no longer show an empty user message, and long tool calls no longer cause horizontal scrolling. (#25586)
-
Removed the "Primitive ID" filter from the metrics dashboard. The metrics API ignored it, so the filter looked active but had no effect. (#25627)
-
Fixed the Studio trace thread view showing observational memory's internal output (such as the observer's capture JSON) as the agent's reply. Observational memory processor runs and their observer/reflector agents are now left out of the reconstructed conversation. (#25565)
-
The trace thread view no longer shows empty rows for task and working-memory tool calls, which the chat already hides. (#25565)
-
Fixed system messages in trace previews showing raw markdown (like
#and**). They are now rendered as formatted text, like user and assistant messages. Long span input and output boxes (Preview and JSON) are now collapsed with an Expand button instead of scrolling inside a fixed height. (#25571)Added
CollapsibleBoxanduseCollapsibleBox: a box that clips content past a measured height with a fade, while you place the expand control anywhere. ThePlancomponent now uses it. -
Thread view now only lists traces from the selected thread when trace query is disabled. (#25593)
-
The "Highlight spans" action for tool calls in the trace thread view now sits on the same line as the tool call instead of below it. (#25593)
-
Fixed variable autocomplete in the code editor leaving leftover text and duplicate closing braces when a suggestion was picked inside an existing {{placeholder}}. (#25638)
@mastra/qdrant@1.1.4
Patch Changes
- Fixed
QdrantVector.deleteVectorsreporting success when Qdrant rejected the request. IDs that are not unsigned integers or UUIDs now throw a clear error instead of silently deleting nothing. (#25529)
@mastra/rag@2.6.6
Patch Changes
- Generate document identifiers with Web Crypto (#25462)
@mastra/react@1.7.1
Patch Changes
-
Fixed Studio agent chat crashing with "Cannot read properties of undefined" when reopening a thread whose finished workflow tool call is replayed from the stream cache. Workflow chunks replayed onto a completed tool result now rebuild the workflow view instead of throwing. (#25497)
-
useChatnow handlestool-call-resumedchunks. It clears the matching suspended tool or pending approval, andisAwaitingToolApprovalbecomesfalseonce no paused tool calls remain in the resumed run. (#25491)const { isAwaitingToolApproval } = useChat({ agentId, threadId, resourceId }); return isAwaitingToolApproval ? <ApprovalPrompt /> : null;
@mastra/schema-compat@1.3.13
Patch Changes
- Fixed OpenAI strict-mode schema preparation rejecting
allOfobject schemas with properties namedconstructor,toString, or__proto__. (#25655)
@mastra/server@1.73.0
Patch Changes
-
Fixed durable agent resume, approve, and decline routes returning 403 to the run's own caller when no auth middleware sets a server-side identity. Requests without an identity are now treated like workflow run ownership checks treat them, while requests with an identity are still checked against the run's resource and thread. Fixes #25511. (#25556)
-
Fixed durable agent resume and tool approval routes returning 403 ("belongs to a different resource" or "tool call is not suspended") when the client resumes immediately after receiving a tool approval event. The access check now waits briefly for the suspended run to be saved before denying the request. (#25611)
-
Use Web Crypto for server-generated IDs and compatible A2A agent-card signatures while preserving legacy PEM key support. (#25462)
-
Fixed Studio showing the wrong provider for durable or dynamic agents that use a gateway model. An agent on
mastra/openai/gpt-5-mininow shows the Mastra gateway instead of OpenAI, so Studio no longer asks forOPENAI_API_KEYwhenMASTRA_GATEWAY_API_KEYis set. (#25620) -
Fixed A2A
tasks/listreturning the full message history whenhistoryLengthis 0. It now returns no history, as requested. (#25607)
@mastra/slack@1.7.1
Patch Changes
- Fixed the Slack provider reporting config drift and re-pushing the app manifest on the first restart after every install that uses slash commands. (#25625)
@mastra/telegram@0.2.1
Patch Changes
- Fixed polling mode allowing the same Telegram bot to be connected to more than one agent. The second
connect()now fails with the same "already connected" error as webhook mode, instead of starting a second poll loop that conflicts with the first. (#25645)
@mastra/upstash@1.5.1
Patch Changes
- Fixed Upstash Vector filters so
{ field: { $not: { $nin: [...] } } }translates tofield IN (...)instead of an invalid inequality. (#25614)
Other updated packages
The following packages were updated with dependency changes only:
- @mastra/agent-builder@1.1.24
- @mastra/arize@1.3.21
- @mastra/arthur@0.4.21
- @mastra/braintrust@1.3.18
- @mastra/datadog@1.4.13
- @mastra/deepeval@0.1.15
- @mastra/deployer-cloud@1.73.0
- @mastra/deployer-cloudflare@1.2.32
- @mastra/deployer-netlify@1.2.32
- @mastra/deployer-vercel@1.2.32
- @mastra/e2b-desktop@0.1.5
- @mastra/laminar@1.3.23
- @mastra/langfuse@1.5.12
- @mastra/langsmith@1.3.23
- @mastra/longmemeval@1.1.32
- @mastra/mcp-docs-server@1.3.3
- @mastra/next@0.2.31
- @mastra/opencode@0.1.32
- @mastra/otel-bridge@1.5.13
- @mastra/otel-exporter@1.4.4
- @mastra/posthog@1.3.15
- @mastra/sentry@1.2.23
- @mastra/tanstack-start@0.2.31
- @mastra/temporal@0.4.11
- @mastra/turso@0.1.11
- @mastra/voice-openai-realtime@0.14.3
- @mastra/voice-xai-realtime@0.2.13