{"record":{"id":"c35be8462531cf7b","repo":"google-gemini/gemini-cli","slug":"failed-to-initialize-remotesessioninvocation-for","errorCode":null,"errorMessage":"Failed to initialize RemoteSessionInvocation for '${definition.name}': A2AClientManager is not available.","messagePattern":"Failed to initialize RemoteSessionInvocation for '(.+?)': A2AClientManager is not available\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/core/src/agents/remote-session-invocation.ts","lineNumber":94,"sourceCode":"  ) {\n    const query = params['query'] ?? DEFAULT_QUERY_STRING;\n    if (typeof query !== 'string') {\n      throw new Error(\n        `Remote agent '${definition.name}' requires a string 'query' input.`,\n      );\n    }\n    // Safe to pass strict object to super\n    super(\n      { query },\n      messageBus,\n      options?.toolName ?? definition.name,\n      options?.toolDisplayName ?? definition.displayName,\n    );\n    this._onAgentEvent = options?.onAgentEvent;\n\n    // Validate that A2AClientManager is available at construction time\n    if (!this.context.config.getA2AClientManager()) {\n      throw new Error(\n        `Failed to initialize RemoteSessionInvocation for '${definition.name}': A2AClientManager is not available.`,\n      );\n    }\n  }\n\n  getDescription(): string {\n    return `Calling remote agent ${this.definition.displayName ?? this.definition.name}`;\n  }\n\n  protected override async getConfirmationDetails(\n    _abortSignal: AbortSignal,\n  ): Promise<ToolCallConfirmationDetails | false> {\n    return {\n      type: 'info',\n      title: `Call Remote Agent: ${this.definition.displayName ?? this.definition.name}`,\n      prompt: `Calling remote agent: \"${this.params.query}\"`,\n      onConfirm: async (_outcome: ToolConfirmationOutcome) => {\n        // Policy updates are now handled centrally by the scheduler","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/core/src/agents/remote-session-invocation.ts#L76-L112","documentation":"Thrown by the RemoteSessionInvocation constructor when config.getA2AClientManager() returns undefined at construction time. The A2AClientManager is the central factory that creates and caches A2A protocol clients for remote agents; without it, the invocation has no transport layer and cannot stream messages to or from a remote agent endpoint. This is a fail-fast guard: the class refuses to instantiate rather than failing later during execute().","triggerScenarios":"Constructing a new RemoteSessionInvocation(definition, context, params, messageBus, options) where context.config.getA2AClientManager() returns undefined. This happens when the Config object's a2aClientManager field was never populated — typically because no remote agents were registered during startup, or the AgentLoopContext was built from a partial/mock config.","commonSituations":"Running remote agent tool calls before the agent registry has initialized the A2A subsystem; using a Config instance in tests that does not wire up a2aClientManager; upgrading to a version where A2AClientManager initialization moved to an async startup phase that hasn't completed; calling the invocation constructor directly instead of going through the registry's tool factory.","solutions":["Ensure remote agents are registered in settings.json or via the agent registry before any RemoteSessionInvocation is constructed, so Config initializes a2aClientManager.","If constructing invocations manually (e.g., in tests), provide a config whose getA2AClientManager() returns a real or mock A2AClientManager instance.","Verify that the AgentLoopContext passed to the constructor shares the same fully-initialized Config instance used by the rest of the application.","Check that any async initialization that populates a2aClientManager has been awaited before the tool call path executes."],"exampleFix":"// before (config not initialized)\nconst invocation = new RemoteSessionInvocation(def, ctx, params, bus);\n\n// after (ensure manager is present first)\nif (!ctx.config.getA2AClientManager()) {\n  throw new Error('Initialize A2A subsystem before invoking remote agents');\n}\nconst invocation = new RemoteSessionInvocation(def, ctx, params, bus);","handlingStrategy":"validation","validationCode":"// Before constructing RemoteSessionInvocation, verify the manager exists\nconst clientManager = context.config.getA2AClientManager();\nif (!clientManager) {\n  throw new Error(\n    `Cannot invoke remote agent '${definition.name}': A2A client manager is not initialized. ` +\n    `Register remote agents or ensure the A2A subsystem has started.`\n  );\n}","typeGuard":"// Type guard for a usable agent loop context for remote sessions\nfunction hasA2AClientManager(\n  ctx: AgentLoopContext\n): ctx is AgentLoopContext & { config: Config & { getA2AClientManager(): NonNullable<ReturnType<Config['getA2AClientManager']>> } } {\n  return ctx.config.getA2AClientManager() != null;\n}","tryCatchPattern":"try {\n  const invocation = new RemoteSessionInvocation(def, ctx, params, bus, opts);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('A2AClientManager is not available')) {\n    // Surface a user-friendly error, retry after init, or skip the agent\n    return { error: 'Remote agent subsystem not ready. Please retry.' };\n  }\n  throw e;\n}","preventionTips":["Always register remote agents before constructing invocations.","In tests, always mock getA2AClientManager to return a non-undefined value.","Centralize invocation construction in the registry so the guard is checked once.","Log a warning during startup if a2aClientManager is undefined but remote agents are configured."],"tags":["a2a","remote-agents","configuration","initialization"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}