google-gemini/gemini-cli · critical · Error

RemoteSubagentProtocol: A2AClientManager not available for '

Error message

RemoteSubagentProtocol: A2AClientManager not available for '${this.definition.name}'.

What it means

Thrown inside RemoteSubagentProtocol._runStream() when config.getA2AClientManager() is undefined at the moment a streaming session starts. Unlike error 220 (which is a construction-time guard in RemoteSessionInvocation), this fires at execution time inside the protocol layer that wraps A2A client streaming behind the AgentProtocol interface. It means the config lost or never had its A2A client manager between session setup and stream start.

Source

Thrown at packages/core/src/agents/remote-subagent-protocol.ts:206

        // Abort resolves with an empty result — partial output is intentionally
        // dropped since the caller requested cancellation.
        this._resultResolve({
          llmContent: [{ text: '' }],
          returnDisplay: '',
        });
      } else {
        this._emitErrorAndAgentEnd(err);
        this._resultReject(err);
      }
    } finally {
      this._clearActiveStream();
    }
  }

  private async _runStream(query: string): Promise<void> {
    const clientManager = this.context.config.getA2AClientManager();
    if (!clientManager) {
      throw new Error(
        `RemoteSubagentProtocol: A2AClientManager not available for '${this.definition.name}'.`,
      );
    }

    const authHandler = await this._getAuthHandler();
    if (!clientManager.getClient(this.definition.name)) {
      await clientManager.loadAgent(
        this.definition.name,
        getAgentCardLoadOptions(this.definition),
        authHandler,
      );
    }

    const reassembler = new A2AResultReassembler();
    let prevText = '';

    const stream = clientManager.sendMessageStream(
      this.definition.name,

View on GitHub (pinned to 5024443c72)

Solutions

  1. Confirm the Config instance backing the AgentLoopContext has a populated a2aClientManager at call time, not just at construction time.
  2. Avoid mutating or replacing the Config object after protocols have been created from it; rebuild protocols if reconfiguring.
  3. In tests, mock config.getA2AClientManager to return a valid client manager for both construction and streaming code paths.
  4. Guard the caller of _runStream with a pre-check: if (!ctx.config.getA2AClientManager()) return an error result to the user instead of throwing.

Example fix

// before
private async _runStream(query: string): Promise<void> {
  const clientManager = this.context.config.getA2AClientManager();
  if (!clientManager) {
    throw new Error(`RemoteSubagentProtocol: A2AClientManager not available...`);
  }
  // ...
}

// after — surface a recoverable error to the caller
private async _runStream(query: string): Promise<void> {
  const clientManager = this.context.config.getA2AClientManager();
  if (!clientManager) {
    this._emitErrorAndAgentEnd(new Error(`A2AClientManager not available for '${this.definition.name}'. Initialize remote agents first.`));
    return;
  }
  // ...
}
Defensive patterns

Strategy: validation

Validate before calling

// Before starting the stream, verify the manager is still present
const clientManager = this.context.config.getA2AClientManager();
if (!clientManager) {
  this._emitErrorAndAgentEnd(
    new Error(`A2AClientManager unavailable for '${this.definition.name}'. Retry after init.`)
  );
  return;
}

Try / catch

try {
  await protocol.send(query);
} catch (e) {
  if (e instanceof Error && e.message.includes('A2AClientManager not available')) {
    // The A2A subsystem may have been torn down; reinitialize or report
    return { error: 'Remote agent transport unavailable. Restart the session.' };
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling send() or startStream() on a RemoteSubagentProtocol instance whose context.config.getA2AClientManager() now returns undefined. This can occur if the config object was mutated or garbage-collected between protocol construction and stream execution, or if the protocol was constructed with a different (incomplete) config context than expected.

Common situations: Long-lived protocol objects whose underlying Config reference became stale after a hot-reload or reconfiguration; race conditions where the A2A subsystem is torn down (e.g., during shutdown) while an in-flight stream request arrives; test setups that construct the protocol with a mock config but forget to mock getA2AClientManager on the streaming path.

Related errors


AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12). Data as JSON: /api/errors/946b3fa78dd0dc91. Report an issue: GitHub.