mastra-ai/mastra · error · MastraError

ATOMIC_STORAGE_OPERATIONS_NOT_SUPPORTED

ATOMIC_STORAGE_OPERATIONS_NOT_SUPPORTED

Error message

Workflow "${this.id}" runs on the evented execution engine, which requires a storage adapter that supports concurrent updates. Your current workflow storage adapter does not. Switch to an adapter that does (for example @mastra/libsql), or, if you do not need scheduled execution, remove the `schedule` field from this workflow's definition to use the default execution engine.

What it means

The evented execution engine requires the workflow storage adapter to support concurrent (atomic) updates — checked via `workflowsStore.supportsConcurrentUpdates()` — because scheduled execution coordinates runs through storage. `createRun()` throws this MastraError (id ATOMIC_STORAGE_OPERATIONS_NOT_SUPPORTED) when a store is configured but reports no concurrent-update support. The user must switch to a capable adapter (e.g. @mastra/libsql) or remove the `schedule` field to fall back to the default engine.

Source

Thrown at packages/core/src/workflows/evented/workflow.ts:1737

    resourceId?: string;
    disableScorers?: boolean;
  }): Promise<Run<TEngineType, TSteps, TState, TInput, TOutput>> {
    if (this.stepFlow.length === 0) {
      throw new Error(
        'Execution flow of workflow is not defined. Add steps to the workflow via .then(), .branch(), etc.',
      );
    }
    if (!this.executionGraph.steps) {
      throw new Error('Uncommitted step flow changes detected. Call .commit() to register the steps.');
    }

    const runIdToUse = options?.runId || randomUUID();

    const workflowsStore = await this.mastra?.getStorage()?.getStore('workflows');

    const supportsConcurrentUpdates = workflowsStore?.supportsConcurrentUpdates?.() ?? false;
    if (workflowsStore && !supportsConcurrentUpdates) {
      throw new MastraError({
        id: 'ATOMIC_STORAGE_OPERATIONS_NOT_SUPPORTED',
        domain: ErrorDomain.MASTRA,
        category: ErrorCategory.USER,
        text:
          `Workflow "${this.id}" runs on the evented execution engine, which requires a storage adapter that supports concurrent updates. ` +
          `Your current workflow storage adapter does not. Switch to an adapter that does (for example @mastra/libsql), or, if you do not need scheduled execution, ` +
          `remove the \`schedule\` field from this workflow's definition to use the default execution engine.`,
        details: { workflowId: this.id },
      });
    }

    // Return a new Run instance with object parameters
    const run: Run<TEngineType, TSteps, TState, TInput, TOutput> =
      this.runs.get(runIdToUse) ??
      new EventedRun({
        workflowId: this.id,
        runId: runIdToUse,
        resourceId: options?.resourceId,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Install and configure a storage adapter that supports concurrent updates, e.g. `@mastra/libsql`, via `Mastra({ storage: new LibSQLStore(...) })`.
  2. If scheduled execution is not needed, remove the `schedule` field from the workflow definition so it uses the default execution engine.
  3. Upgrade your existing storage adapter to the latest version — concurrent-update support was added over time.
  4. Feature-check before startup: call `supportsConcurrentUpdates()` on your store during boot and fail fast with a clear message.

Example fix

// before
new Mastra({ storage: new InMemoryStore() }); // workflow has schedule: {...}

// after
import { LibSQLStore } from '@mastra/libsql';
new Mastra({ storage: new LibSQLStore({ url: 'file:./mastra.db' }) });
// or: remove `schedule` from the workflow params
Defensive patterns

Strategy: validation

Validate before calling

async function assertStorageSupportsEvented(mastra: Mastra, workflow: Workflow): Promise<void> {
  const store = await mastra.getStorage()?.getStore('workflows');
  const ok = store?.supportsConcurrentUpdates?.() ?? false;
  if (!ok && (workflow as any).params?.schedule) {
    throw new Error('Scheduled evented workflows need a storage adapter with concurrent updates (e.g. @mastra/libsql)');
  }
}
await assertStorageSupportsEvented(mastra, workflow);

Type guard

function supportsConcurrentUpdates(store: unknown): store is { supportsConcurrentUpdates: () => boolean } {
  return !!store && typeof (store as any).supportsConcurrentUpdates === 'function' && (store as any).supportsConcurrentUpdates() === true;
}

Try / catch

try {
  const run = await workflow.createRun();
} catch (e) {
  if (e instanceof MastraError && e.id === 'ATOMIC_STORAGE_OPERATIONS_NOT_SUPPORTED') {
    // swap storage adapter or remove workflow schedule
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `createRun()` on a scheduled workflow running on the evented engine where `this.mastra.getStorage().getStore('workflows')` returns a store whose `supportsConcurrentUpdates()` returns false/undefined (workflow.ts:1733-1747).

Common situations: Using an in-memory or legacy storage adapter (or one without `supportsConcurrentUpdates`) with scheduled workflows; deploying to an environment where the configured storage lacks atomic operations; following older setup guides that predate the concurrent-updates requirement.

Related errors


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