{"record":{"id":"b9f3fc5bde10dc45","repo":"mastra-ai/mastra","slug":"runid-required-to-observe-workflow-stream","errorCode":null,"errorMessage":"runId required to observe workflow stream","messagePattern":"runId required to observe workflow stream","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"packages/server/src/server/handlers/workflows.ts","lineNumber":775,"sourceCode":"  responseType: 'stream',\n  pathParamSchema: workflowIdPathParams,\n  queryParamSchema: observeWorkflowQuerySchema,\n  responseSchema: streamResponseSchema,\n  summary: 'Observe workflow stream',\n  description:\n    'Observes and streams updates from an already running workflow execution. Supports position-based resume with offset for efficient reconnection.',\n  tags: ['Workflows'],\n  requiresAuth: true,\n  handler: async ({ mastra, workflowId, runId, offset, requestContext }) => {\n    try {\n      const effectiveResourceId = getEffectiveResourceId(requestContext, undefined);\n\n      if (!workflowId) {\n        throw new HTTPException(400, { message: 'Workflow ID is required' });\n      }\n\n      if (!runId) {\n        throw new HTTPException(400, { message: 'runId required to observe workflow stream' });\n      }\n\n      const { workflow } = await listWorkflowsFromSystem({ mastra, workflowId });\n\n      if (!workflow) {\n        throw new HTTPException(404, { message: 'Workflow not found' });\n      }\n\n      const run = await workflow.getWorkflowRunById(runId);\n\n      if (!run) {\n        throw new HTTPException(404, { message: 'Workflow run not found' });\n      }\n\n      await validateRunOwnership(run, effectiveResourceId);\n\n      const _run = await workflow.createRun({ runId, resourceId: run.resourceId });\n      const serverCache = mastra.getServerCache();","sourceCodeStart":757,"sourceCodeEnd":793,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/workflows.ts#L757-L793","documentation":"A 400 validation error thrown by the observe-workflow-stream handler when the runId parameter is missing. Observing a stream requires identifying which existing run's stream to attach to.","triggerScenarios":"POSTing to the observe-stream route without runId in body/query.","commonSituations":"Calling observe before creating/starting a run; client code losing the runId returned by createRun; confusing the observe route with the start route (which doesn't require runId).","solutions":["Create or obtain a run first and pass its runId when observing the stream","Persist the runId returned by createRun/start and reuse it","Use the start-run route instead if you intended to launch a new run"],"exampleFix":"// before\nawait run.observeStream({}); // server route requires runId\n// after\nconst run = await client.getWorkflow('wf').createRun();\nawait client.getWorkflow('wf').observeStream({ runId: run.runId });","handlingStrategy":"validation","validationCode":"function assertRunId(id: string | undefined): asserts id is string {\n  if (!id) throw new Error('runId is required — create or start a run first');\n}","typeGuard":"function hasRunId(p: { runId?: string }): p is { runId: string } {\n  return typeof p.runId === 'string' && p.runId.length > 0;\n}","tryCatchPattern":"try {\n  await observeStream({ workflowId, runId });\n} catch (e: any) {\n  if (e?.status === 400 && /runId required/.test(e?.message ?? '')) {\n    const run = await client.getWorkflow(workflowId).createRun();\n    // retry with run.runId\n  } else throw e;\n}","preventionTips":["Always capture the runId returned by createRun/start","Distinguish start vs observe vs resume flows in client code","Add unit tests that cover the observe path with a real runId"],"tags":["http-400","validation","mastra-server"],"backgroundTag":"missing-required-parameter","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}