{"record":{"id":"b9e5946b680e2fdf","repo":"mastra-ai/mastra","slug":"no-active-agent-run-found-for-signal-target","errorCode":null,"errorMessage":"No active agent run found for signal target","messagePattern":"No active agent run found for signal target","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/agent/thread-stream-runtime.ts","lineNumber":2811,"sourceCode":"        } else {\n          // Stale cross-pod entry. Clean it up from the local map, then let the lease decide\n          state.activeThreadRunIds.delete(key);\n          state.activeThreadStreamIds.delete(key);\n        }\n      }\n    }\n\n    if (runId) {\n      activeRecord ??= state.threadRunsById.get(runId);\n      if (activeRecord) {\n        key ??= this.#threadKey(activeRecord.resourceId, activeRecord.threadId);\n      }\n    }\n\n    const resourceId = target.resourceId ?? activeRecord?.resourceId;\n    const threadId = target.threadId ?? activeRecord?.threadId;\n    if (!resourceId || !threadId) {\n      throw new Error('No active agent run found for signal target');\n    }\n\n    const isActiveTarget = Boolean(\n      runId && (activeRecord?.output.status === 'running' || (key && state.activeThreadRunIds.get(key) === runId)),\n    );\n    let signal = createSignal({\n      ...signalInput,\n      id: signalInput.id ?? this.#generateSignalMessageId(agent, { resourceId, threadId }),\n      acceptedAt: new Date(),\n    });\n\n    // Resolve conditional delivery attributes now that we know the delivery path.\n    signal = resolveDeliveryAttributes(\n      signal,\n      isActiveTarget ? target.ifActive?.attributes : target.ifIdle?.attributes,\n    );\n\n    if (isActiveTarget && activeBehavior !== 'deliver') {","sourceCodeStart":2793,"sourceCodeEnd":2829,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/agent/thread-stream-runtime.ts#L2793-L2829","documentation":"Thrown by the signal-sending path (sendSignal / signal APIs) when no resourceId/threadId can be resolved from the target or from an active run record, i.e. there is no active agent run matching the signal target. The runtime cannot determine which thread the signal belongs to.","triggerScenarios":"Calling the signal API with only a runId whose record is no longer active (run finished/cleaned up), or with an empty target and no running thread run; race where the run completed between lookup and signal dispatch.","commonSituations":"Signaling a run after it already finished (async listener fires late); stale runIds cached by the client; signaling on a server instance that doesn't own the run (distributed setups without shared pubsub state).","solutions":["Pass explicit resourceId and threadId in the target instead of relying on an active run lookup.","Before signaling, confirm the run is still active (e.g. check run status) and handle the finished-run case.","Use ifIdle options so the signal has a defined idle-path target with full thread IDs."],"exampleFix":"// before\nawait runtime.sendSignal(agent, signalInput, { runId }); // run may be gone\n// after\nawait runtime.sendSignal(agent, signalInput, { runId, resourceId: 'user-1', threadId: 'thread-1' });","handlingStrategy":"validation","validationCode":"if (!target.resourceId || !target.threadId) {\n  // resolve from your own run registry before signaling\n  const rec = myRuns.get(target.runId);\n  if (!rec || rec.status !== 'running') throw new Error('No active run for signal target');\n  target.resourceId ??= rec.resourceId;\n  target.threadId ??= rec.threadId;\n}","typeGuard":"null","tryCatchPattern":"try {\n  return await runtime.sendSignal(agent, input, target);\n} catch (e) {\n  if (e instanceof Error && e.message === 'No active agent run found for signal target') {\n    // run already finished or unknown runId — treat as a no-op or recreate context\n  }\n  throw e;\n}","preventionTips":["Pass resourceId/threadId explicitly instead of relying on active-run inference","Treat runIds as ephemeral: don't cache them across long-lived processes","Use shared pubsub state in distributed setups","Check run liveness before dispatching signals"],"tags":["agent","signal","race-condition","missing-argument"],"backgroundTag":"missing-thread-context","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}