mastra-ai/mastra · error · Error

[${this.id}] Cannot send notification: no agent connected. W

Error message

[${this.id}] Cannot send notification: no agent connected. Was this provider passed to Agent({ signals: [...] })?

What it means

Signal providers can only send notifications through an agent they are connected to. notify() reads the internal #connectedAgent reference, and if it is unset the provider throws. Connection happens when the provider instance is passed to an Agent via the Agent({ signals: [...] }) option; a bare-constructed provider has no agent and cannot notify.

Source

Thrown at packages/core/src/signals/signal-provider.ts:457

  stop(): void {
    this.stopPolling();
    this.#subscriptions.clear();
    this.#subscriptionsByResource.clear();
    this.#subscriptionsByThread.clear();
  }

  // ── Convenience ────────────────────────────────────────────────────

  /**
   * Send a notification signal to the connected agent.
   * Convenience wrapper around `this.agent.sendNotificationSignal()`.
   *
   * @throws If no agent is connected
   */
  protected async notify(notification: SendNotificationSignalInput, target: SignalProviderTarget): Promise<void> {
    const agent = this.#connectedAgent;
    if (!agent) {
      throw new Error(
        `[${this.id}] Cannot send notification: no agent connected. Was this provider passed to Agent({ signals: [...] })?`,
      );
    }

    await agent.sendNotificationSignal(notification, {
      resourceId: target.resourceId,
      threadId: target.threadId,
      ...(target.ifIdle ? { ifIdle: target.ifIdle } : {}),
    });
  }

  // ── Internal ───────────────────────────────────────────────────────

  #subscriptionKey(target: SignalProviderTarget, externalResourceId: string): string {
    return `${target.resourceId}:${target.threadId}:${externalResourceId}`;
  }

  #threadKey(target: SignalProviderTarget): string {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Pass the provider instance to Agent({ signals: [provider] }) so it gets connected, then use that same agent-backed flow.
  2. Ensure you pass the SAME provider instance to the agent — a second `new MyProvider()` creates an unconnected clone.
  3. If the notification must be sent without an agent, don't use notify(); use the provider's lower-level delivery mechanism directly instead.

Example fix

// before
const provider = new SlackSignalProvider({ token });
await provider.notify(notification, target); // throws: no agent
// after
const provider = new SlackSignalProvider({ token });
const agent = new Agent({ name: 'my-agent', signals: [provider], ... });
// now provider.notify(...) (or poll/webhook) resolves through agent.sendNotificationSignal
Defensive patterns

Strategy: validation

Validate before calling

function assertProviderConnected(provider) {
  const connected = provider.notify !== undefined && provider['#connectedAgent'] !== undefined;
  // prefer an exposed isConnected() if available:
  // if (!provider.isConnected?.()) throw new Error('Signal provider not connected to an agent');
  return connected;
}
// Otherwise, guarantee wiring at construction:
const provider = new MySignalProvider(opts);
const agent = new Agent({ name: 'a', signals: [provider] });
if (agent !== null && provider == null) throw new Error('unreachable');

Type guard

function isAgentConnected(provider) {
  return provider != null && typeof provider.notify === 'function' &&
    // the provider stores its connected agent in a private field;
    // expose/observe via a successful dry-run or an isConnected() API when available
    Boolean(provider.isConnected?.());
}

Try / catch

try {
  await provider.notify(notification, target);
} catch (e) {
  if (String(e?.message).includes('no agent connected')) {
    console.error('Provider not wired to an Agent — pass it to Agent({ signals: [...] }) using the SAME instance');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling provider.notify(notification, target) (directly or via doNotify/poll/handleWebhook) on a provider that was instantiated but never passed into an Agent's signals array.

Common situations: Using a signal provider standalone (e.g. calling poll() or invoking a webhook handler) without wiring it to an agent; creating a new provider instance in one module while the agent was configured with a different instance; tests instantiating a provider to call notify() without an Agent fixture.

Related errors


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