github mastra-ai/mastra @mastra/core@1.25.0
April 15, 2026

latest releases: mastracode@0.16.2, mastra@1.7.2, create-mastra@1.7.2...
5 hours ago

Highlights

Per-user resource scoping in server auth (secure by default)

Server auth now supports mapUserToResourceId, automatically mapping an authenticated user to a resource ID so memory/threads are isolated per user without custom middleware, and client attempts to inject reserved context keys (mastra__resourceId, mastra__threadId) are stripped.

Experiments + observability are now version-aware end-to-end

Experiments correctly execute the specified agentVersion, and observability gains first-class entityVersionId/parentEntityVersionId/rootEntityVersionId across spans/metrics/scores/logs/feedback (with storage migrations in ClickHouse/DuckDB/Postgres/MongoDB/LibSQL), plus new experiment query filters and experimentId propagation into agent spans and scorer context.

Agent version targeting in AI SDK route handlers

chatRoute(), handleChatStream(), networkRoute(), and handleNetworkStream() now accept agentVersion (and runtime ?versionId= / ?status= overrides) to route traffic to draft/published or specific version IDs (requires the Editor).

Tool calling reliability upgrades: strict mode + better API error recovery

You can enable per-tool strict: true in createTool() for providers that support strict tool calling, and processors can now intercept LLM failures via processAPIError (including a built-in PrefillErrorHandler that retries Anthropic “assistant message prefill” errors automatically).

Browser automation persistence & stability improvements

Agent Browser/Stagehand add lightweight auth persistence via storageState/exportStorageState(), support persistent sessions via profile and custom Chrome via executablePath, and improve cleanup (stale lock files/orphaned Chrome processes) for more reliable runs.

Breaking Changes

  • @mastra/voice-sarvam@1.0.0 drops deprecated Sarvam models (bulbul:v1, saarika:v1/v2/flash), defaults shift to bulbul:v3 + speaker shubh, and the TTS request payload changes from inputs[] to text.

Changelog

@mastra/core@1.25.0

Minor Changes

  • feat(server): Add mapUserToResourceId callback to auth config for automatic resource ID scoping (#13954)

    Auth configs now accept a mapUserToResourceId callback that maps the authenticated user to a resource ID after successful authentication. This enables per-user memory and thread isolation without requiring custom middleware or adapter subclassing.

    const mastra = new Mastra({
      server: {
        auth: {
          authenticateToken: async token => verifyToken(token),
          mapUserToResourceId: user => user.id,
        },
      },
    });

    The callback is called in coreAuthMiddleware after the user is authenticated and set on the request context. The returned value is set as MASTRA_RESOURCE_ID_KEY, which takes precedence over client-provided values for security. Works across all server adapters (Hono, Express, Next.js, etc.).

  • Added processAPIError hook to the Processor interface for intercepting LLM API call failures before they surface as errors. New built-in PrefillErrorHandler automatically recovers from Anthropic "assistant message prefill" errors by appending a <system-reminder>continue</system-reminder> user message and retrying once. (#14435)

  • Experiments now run the correct agent version (#15317)

    When an experiment specifies agentVersion, the experiment pipeline now resolves and executes against that specific version instead of ignoring it. Previously, the version was stored as metadata but the agent always ran with its current default configuration.

    entityVersionId is now a first-class observability dimension

    New entityVersionId, parentEntityVersionId, and rootEntityVersionId fields are available on all observability records (spans, metrics, scores, feedback, logs). This enables filtering and grouping OLAP queries by version at any level of the span tree. rootEntityVersionId is particularly useful for aggregating all signals within a versioned agent's trace. This replaces the previous resolvedVersionId attribute which was buried in span attributes and unfilterable.

    experimentId propagated to agent spans

    Agent spans created during experiment execution now carry the experimentId, enabling trace-to-experiment cross-referencing.

    Scorer correlation context

    Scorers running in the experiment pipeline now receive full targetCorrelationContext (including experimentId), so scores emitted via observability carry experiment context.

    New experiment query filters

    listExperiments now supports filtering by targetType, targetId, agentVersion, and status. listExperimentResults now supports filtering by traceId and status.

  • Added profile and executablePath options to browser config for persistent sessions and custom browser support. Automatically cleans up stale Chrome lock files on browser close. (#15194)

  • Added (#15313)
    Added per-tool strict mode for providers that support strict tool calling. You can now set strict: true on createTool() and Mastra will forward it when preparing tool definitions.

    const weatherTool = createTool({
      id: 'weather',
      description: 'Get weather for a city',
      strict: true,
      inputSchema: z.object({ city: z.string() }),
      execute: async ({ city }) => ({ city }),
    });

Patch Changes

  • Update provider registry and model documentation with latest models and providers (582644c)

  • Fixed mastra_workspace_list_files silently returning no files when agents passed an empty pattern (e.g. pattern: [] or pattern: ''). Empty and whitespace-only patterns are now treated as "no filter" and return the full listing instead of a dirs-only view or a picomatch error. (#15360)

    Fixed harness tool approval, decline, and resume handlers hardcoding requireToolApproval: true. They now follow the harness yolo state like sendMessage already does, so resumed tool calls in yolo mode no longer get unexpectedly re-gated on approval.

  • Update references to "Mastra Cloud" to "Mastra platform" (#15297)

  • Fixed symlinked skill paths so workspace skills resolve consistently and allowed path checks work through both symlink and real paths. (#15228)

  • AgentBrowser with default thread scope now initializes correctly. Previously, calling launch() followed by getPage() would throw "Browser not launched" when no explicit thread ID was provided. (#15285)

  • fix: ensure listVectorStores always returns a string id (#15239)

  • Improved structuredOutput.model error messages to surface upstream structuring failures, including plain-object errors, instead of a generic internal agent error. (#15226)

  • Agent instances can now create lightweight clones that preserve all configuration, so version overrides and tools are isolated without mutating the shared runtime agent. (#15314)

  • Fixed structuredOutput.model custom gateway resolution by registering the internal structuring agent with the parent Mastra instance. (#15230)

  • Fixed OpenAI reasoning summary streaming so reasoning summary text is preserved when multiple summaries overlap or finish out of order. (#15225)

  • Upgraded model router providers to AI SDK v3 spec: OpenAI, Anthropic, Google, xAI, Groq, and Mistral now use the latest v6 SDK packages. Providers built on openai-compatible (Cerebras, DeepInfra, DeepSeek, Perplexity, TogetherAI) remain on v2 spec until their base package is updated. All provider packages (both v5 and v6) bumped to their latest stable patch versions. (#15358)

    Fixed 'item missing its reasoning part' error for OpenAI reasoning models (gpt-5-mini, gpt-5.2). The v5 SDK couldn't serialize reasoning items for OpenAI's Responses API, so Mastra stripped them from prompts — but this caused errors in multi-turn conversations with memory enabled. With v3 providers, reasoning items are serialized natively and the stripping workaround has been removed.

  • Fixed gateway model detection to use duck typing instead of instanceof check, preventing potential failures from cross-package module resolution issues. Propagates gatewayId through the AISDKV5LanguageModel wrapper so duck-type detection works even when models are re-wrapped. (#15168)

  • Fixed Channels not working on Vercel serverless (and other serverless platforms). Webhook handlers now await initialization on cold starts instead of immediately returning 503, and pass the platform's waitUntil to the Chat SDK so agent processing survives after the HTTP response is sent. See #15300. (#15335)

  • fix(core): Restore AI SDK v6 provider option typings for vector embeddings (#15306)

    The vendored AI SDK v6 declaration build now re-exports ProviderOptions after type bundling renames it to ProviderOptions_2. This fixes TS2724 errors in @mastra/core when vector embeddings import AI SDK v6 provider option types.

@mastra/agent-browser@0.2.0

Minor Changes

  • Added storageState option and exportStorageState() method for lightweight auth persistence (cookies and localStorage). Also kills orphaned Chrome child processes on close to prevent zombies. (#15194)

Patch Changes

  • AgentBrowser with default thread scope now initializes correctly. Previously, calling launch() followed by getPage() would throw "Browser not launched" when no explicit thread ID was provided. (#15285)

@mastra/ai-sdk@1.4.0

Minor Changes

  • Added structured output streaming to the AI SDK UI stream. When an agent produces structured output, the final object is now emitted as a data-structured-output data part in the UI message stream, making it available to frontends via AI SDK UI's custom data handling. (#15237)

  • Added agent versioning support to chat and network route handlers. You can now pass agentVersion to chatRoute(), handleChatStream(), networkRoute(), and handleNetworkStream() to target a specific agent version by ID or status (draft/published). Route handlers also accept ?versionId=<id> or ?status=draft|published query parameters at request time, which take precedence over static configuration. Requires the Editor to be configured. (#15296)

    // Static version on route config
    chatRoute({
      path: '/chat',
      agent: 'weatherAgent',
      agentVersion: { status: 'published' },
    });
    
    // Programmatic version on handler
    const stream = await handleChatStream({
      mastra,
      agentId: 'weatherAgent',
      agentVersion: { versionId: 'ver_abc123' },
      params,
    });

Patch Changes

  • Fixed reasoning streams so reasoning UI parts are only emitted when reasoning content is included. (#15207)

@mastra/clickhouse@1.4.1

Patch Changes

  • Added entityVersionId, parentEntityVersionId, and rootEntityVersionId columns to observability storage tables (spans, metrics, scores, feedback, logs) for filtering and grouping traces by entity version. Added ALTER TABLE migrations for existing databases. Added targetType, targetId, agentVersion, and status filters to listExperiments, and traceId and status filters to listExperimentResults. (#15317)

@mastra/duckdb@1.1.2

Patch Changes

  • Added entityVersionId, parentEntityVersionId, and rootEntityVersionId columns to observability storage tables (spans, metrics, scores, feedback, logs) for filtering and grouping traces by entity version. Added ALTER TABLE migrations for existing databases. Added targetType, targetId, agentVersion, and status filters to listExperiments, and traceId and status filters to listExperimentResults. (#15317)

@mastra/editor@0.7.16

Patch Changes

  • Resolving stored agent versions no longer mutates the shared singleton agent instance. Instruction and tool overrides are now applied to an isolated clone, making concurrent version resolution safe and preventing overrides from leaking onto the global agent. (#15314)

@mastra/libsql@1.8.1

Patch Changes

  • Fixed "column does not exist" errors when using experiment review features on databases created before the review pipeline was introduced. Startup now automatically migrates older experiment tables to the latest schema. (#15304)

  • Added entityVersionId, parentEntityVersionId, and rootEntityVersionId columns to observability storage tables (spans, metrics, scores, feedback, logs) for filtering and grouping traces by entity version. Added ALTER TABLE migrations for existing databases. Added targetType, targetId, agentVersion, and status filters to listExperiments, and traceId and status filters to listExperimentResults. (#15317)

@mastra/mcp@1.5.0

Minor Changes

  • Added requireToolApproval option to MCP server configuration for requiring human approval before tool execution. Supports both boolean (all tools) and function (dynamic per-tool logic). (#15315)

Patch Changes

  • Preserve forwarded MCP client elicitation capabilities so client-supported URL and form elicitations work correctly. (#15233)

@mastra/memory@1.15.1

Patch Changes

  • Fixed gateway model detection to use duck typing instead of instanceof check, preventing potential failures from cross-package module resolution issues. Propagates gatewayId through the AISDKV5LanguageModel wrapper so duck-type detection works even when models are re-wrapped. (#15168)

@mastra/mongodb@1.7.1

Patch Changes

  • Added entityVersionId, parentEntityVersionId, and rootEntityVersionId columns to observability storage tables (spans, metrics, scores, feedback, logs) for filtering and grouping traces by entity version. Added ALTER TABLE migrations for existing databases. Added targetType, targetId, agentVersion, and status filters to listExperiments, and traceId and status filters to listExperimentResults. (#15317)

@mastra/observability@1.9.1

Patch Changes

  • Fixed double-counting of Anthropic cache tokens in usage metrics (#15316)

  • Cost estimates now use the latest model pricing rates for more accurate calculations (#15362)

  • Update references to "Mastra Cloud" to "Mastra platform" (#15297)

  • Reduced observability overhead for MODEL_STEP spans by storing a lightweight message preview of request bodies. (#15249)

    This keeps span previews readable and avoids pulling large payloads into exporter input.

  • Fixed cost lookup for models with date suffixes. Providers like OpenAI often return model names with date suffixes (e.g., gpt-5.4-mini-2026-03-17) that don't exactly match pricing data entries. The lookup now tries multiple variants including stripping date suffixes and converting dots to dashes. (#15349)

  • Added entityVersionId, parentEntityVersionId, and rootEntityVersionId to span correlation context, enabling version information to propagate to scores, metrics, logs, and feedback emitted during traced execution. (#15317)

  • Fixed stack traces for errors reported to Sentry. Exceptions now point to the code that threw the error instead of SentryExporter.handleSpanEnded inside the exporter, so issues in Sentry are actually debuggable. (#15343)

    This was caused by two issues, both fixed:

    • @mastra/sentry passed the error message as a string to Sentry.captureException, which made Sentry synthesize a stack trace from the exporter's call site. It now passes an Error instance with the captured stack attached.
    • @mastra/observability stored the wrapping MastraError's stack on the span, hiding the original error's location. When the MastraError has a cause, the cause's stack is now preserved.

    Fixes #15337.

@mastra/pg@1.9.1

Patch Changes

  • Fixed vector similarity queries to leverage HNSW and IVFFlat indexes. When querying without filters on an HNSW or IVFFlat-indexed table, ORDER BY and LIMIT are now placed inside the CTE so PostgreSQL can use the index for faster approximate nearest neighbor searches instead of scanning all rows. (#14574)

  • Fixed batchInsert and batchUpdate in @mastra/pg to run on a single Postgres transaction connection. (#15312)

    This prevents pooled BEGIN/COMMIT/ROLLBACK calls from landing on different connections and leaving idle transactions open during batch writes.

  • Fixed "column does not exist" errors when using experiment review features on databases created before the review pipeline was introduced. Startup now automatically migrates older experiment tables to the latest schema. (#15304)

  • Fixed vector operations failing when pgvector extension is installed in a custom schema. The search_path is now set before index creation and vector similarity queries, ensuring operator classes (e.g. vector_cosine_ops) and distance operators (e.g. <=>) resolve correctly regardless of where the extension is installed. Previously, only table creation set the search_path, causing CREATE INDEX and query operations to fail with unresolvable operator errors. (#14526)

  • Added entityVersionId, parentEntityVersionId, and rootEntityVersionId columns to observability storage tables (spans, metrics, scores, feedback, logs) for filtering and grouping traces by entity version. Added ALTER TABLE migrations for existing databases. Added targetType, targetId, agentVersion, and status filters to listExperiments, and traceId and status filters to listExperimentResults. (#15317)

@mastra/playground-ui@22.1.2

Patch Changes

  • Added PageLayout and PageHeader compound components for consistent page structure across Mastra Studio, plus a NoDataPageLayout helper for 401/403/empty/error states. (#15243)

    List components (AgentsList, WorkflowsList, ToolsList, ProcessorsList, McpServersList, PromptsList, LogsList, ObservabilityTracesList) no longer handle errors or empty states internally — handle those at the page level. If you consume these components directly, move error/empty-state rendering to the parent.

  • Fix dataset detail tab badges to use total item and experiment counts instead of currently loaded rows. (#14994)

  • Added EntityList.Pagination sub-component for server-side pagination of EntityList views. Mirrors the existing ItemList.Pagination API. (#15353)

  • Added ValueLink, ValueWithTooltip, and ValueWithCopyBtn variants to DataKeysAndValues component (#15208)

  • Refresh Studio Evaluation pages with an updated UI and flattened top-level URLs (/scorers, /datasets, /experiments; /evaluation remains as the overview). @mastra/playground-ui removes EvaluationDashboard and all Evaluation*-prefixed list components, constants, and hooks — use the per-domain replacements (e.g. ScorersList) instead. (#15258)

  • Fixed DataList to only take as much height as its content needs instead of always stretching to fill available space (#15291)

@mastra/posthog@1.0.17

Patch Changes

  • Fixed generation traces producing stringified JSON in messages instead of structured content. Input messages wrapped as {messages: [...]} and output objects with text are now properly extracted and formatted. (#15203)

@mastra/schema-compat@1.2.8

Patch Changes

  • --- (#14624)
    @mastra/schema-compat: patch


    Improved provider schema compatibility for structured outputs and tool calls.
    Fixed validation for optional, nullable, and defaulted fields, and for ISO date strings returned for date fields.

@mastra/sentry@1.0.16

Patch Changes

  • Fixed stack traces for errors reported to Sentry. Exceptions now point to the code that threw the error instead of SentryExporter.handleSpanEnded inside the exporter, so issues in Sentry are actually debuggable. (#15343)

    This was caused by two issues, both fixed:

    • @mastra/sentry passed the error message as a string to Sentry.captureException, which made Sentry synthesize a stack trace from the exporter's call site. It now passes an Error instance with the captured stack attached.
    • @mastra/observability stored the wrapping MastraError's stack on the span, hiding the original error's location. When the MastraError has a cause, the cause's stack is now preserved.

    Fixes #15337.

@mastra/server@1.25.0

Minor Changes

  • feat(server): Add mapUserToResourceId callback to auth config for automatic resource ID scoping (#13954)

    Auth configs now accept a mapUserToResourceId callback that maps the authenticated user to a resource ID after successful authentication. This enables per-user memory and thread isolation without requiring custom middleware or adapter subclassing.

    const mastra = new Mastra({
      server: {
        auth: {
          authenticateToken: async token => verifyToken(token),
          mapUserToResourceId: user => user.id,
        },
      },
    });

    The callback is called in coreAuthMiddleware after the user is authenticated and set on the request context. The returned value is set as MASTRA_RESOURCE_ID_KEY, which takes precedence over client-provided values for security. Works across all server adapters (Hono, Express, Next.js, etc.).

Patch Changes

  • fix(server): Strip reserved context keys from client-provided requestContext (#13954)

    Clients could inject mastra__resourceId or mastra__threadId via the request body or query params to impersonate other users' memory/thread access. Reserved keys are now filtered out during request context creation in mergeRequestContext, so only server-side code (auth callbacks, middleware) can set them.

@mastra/stagehand@0.2.0

Minor Changes

  • Added automatic cleanup on browser close: patches exit_type to prevent restore dialogs, kills orphaned Chrome child processes, and uses CDP events for reliable disconnect detection in both shared and thread scope. (#15194)

Patch Changes

@mastra/voice-sarvam@1.0.0

Major Changes

  • Added support for Sarvam's current TTS and STT models. Previously the package only supported the now-deprecated bulbul:v1 and saarika:v1/v2/flash models, which Sarvam has retired. (#15204)

    What's new:

    • TTS models: bulbul:v2, bulbul:v3 (default), and bulbul:v3-beta. bulbul:v3 and bulbul:v3-beta support 39 speakers; bulbul:v2 supports 7 speakers.
    • STT models: saarika:v2.5 (default) and saaras:v3. saaras:v3 is a multi-mode model that supports transcribe, translate, verbatim, translit, and codemix via a new mode option.
    • New bulbul:v3 parameters: temperature, dict_id, output_audio_codec.
    • Expanded speech_sample_rate options: 8000, 16000, 22050, 24000, 32000, 44100, 48000.

    Breaking changes:

    • Removed the deprecated bulbul:v1 TTS model and its speakers (meera, pavithra, maitreyi, arvind, amol, amartya, diya, neel, misha, vian, arjun, maya). Sarvam has retired the underlying API.
    • Removed the deprecated saarika:v1, saarika:v2, and saarika:flash STT models.
    • The default TTS model is now bulbul:v3 and the default speaker is shubh. Speakers are not interchangeable between bulbul versions — each has its own catalog.
    • The TTS request body now sends text (single string) instead of inputs (array), matching Sarvam's current API.

    Migration:

    Before:

    const voice = new SarvamVoice({
      speechModel: { model: 'bulbul:v1', language: 'en-IN' },
      speaker: 'meera',
      listeningModel: { model: 'saarika:v2' },
    });

    After:

    const voice = new SarvamVoice({
      speechModel: { model: 'bulbul:v3', language: 'en-IN' },
      speaker: 'shubh',
      listeningModel: { model: 'saarika:v2.5' },
    });
    
    // Or use saaras:v3 for speech translation:
    await voice.listen(audio, { model: 'saaras:v3', mode: 'translate' });

    Resolves #15188.

Patch Changes

Other updated packages

The following packages were updated with dependency changes only:

Don't miss a new mastra release

NewReleases is sending notifications on new releases.