Skip to content

Bundled proxy-agent fallback can still fail with "HttpsProxyAgent is not a constructor" after #26361 #27143

Description

@ashishch432

What happened?

After #26361, the known Vertex AI contentGenerator path is protected by passing an explicit proxy agent through googleAuthOptions.clientOptions.transporterOptions.agent.

However, the underlying bundled fallback path still appears broken. In the published/bundled CLI, a gaxios instance that has no explicit opts.agent, sees HTTPS_PROXY / HTTP_PROXY, and reaches its lazy proxy-agent import can still fail with:

TypeError: HttpsProxyAgent3 is not a constructor

I hit this on the nightly package with Vertex AI auth using GOOGLE_APPLICATION_CREDENTIALS for an external-account / service-account-impersonation credential source.

This seems related to #24471, but not fully covered by #26361. #26361 avoids the dynamic import path for the main GoogleGenAI / Google Auth construction path. This issue is about the remaining bundled dynamic-import fallback itself.

Observed stack:

TypeError: HttpsProxyAgent3 is not a constructor
    at #prepareRequest (.../node_modules/@google/gemini-cli/bundle/chunk-HJJZ4LMX.js:6933:26)
    at async Gaxios.request (...)
    at async _StsCredentials.exchangeToken (...)
    at async #internalRefreshAccessTokenAsync (...)
    at async _IdentityPoolClient.refreshAccessTokenAsync (...)
    at async _IdentityPoolClient.getAccessToken (...)
    at async _IdentityPoolClient.getRequestHeaders (...)
    at async NodeAuth.addGoogleAuthHeaders (...)
    at async ApiClient.getHeadersInternal (...)

The same flow run from source with npm run start did not reproduce, which points to generated bundle behavior rather than normal Node module resolution.

What did you expect to happen?

Gemini CLI should consistently use the configured proxy without throwing a constructor error, regardless of whether the request path receives an explicit pre-instantiated agent or falls back to gaxios proxy handling.

If the bundled code reaches:

await import('https-proxy-agent')

then the generated bundle should expose a constructable HttpsProxyAgent at the named export location expected by gaxios.

Client information

Client Information

Please paste your /about output here.

Known affected environment from local investigation:

node=v25.8.2
platform=darwin
arch=arm64
package.version=0.44.0-nightly.20260512.g022e8baef
auth=Vertex AI
credential shape=GOOGLE_APPLICATION_CREDENTIALS external account JSON using service account impersonation
https-proxy-agent=7.0.6
gaxios=6.7.1
google-auth-library=9.15.1
@google/genai=1.30.0
@google/genai nested gaxios=7.1.3
@google/genai nested google-auth-library=10.5.0

Login information

Vertex AI auth using GOOGLE_APPLICATION_CREDENTIALS.
The credential file is an external-account JSON with a local credential source and service account impersonation.

Anything else we need to know?

Local bundle analysis suggests the failing path is an esbuild ESM splitting / CommonJS interop issue.

In normal Node module loading:

const mod = await import('https-proxy-agent');
typeof mod.HttpsProxyAgent === 'function'

But in the generated Gemini CLI bundle, the split helper chunk shape was:

dist-*.js.keys=["default"]
dist-*.js.default.keys=["HttpsProxyAgent"]
dist-*.js.HttpsProxyAgent.type=undefined
dist-*.js.default.HttpsProxyAgent.type=function

Bundled gaxios@7.x expects the named export:

this.#proxyAgent ||= (await import("./dist-*.js")).HttpsProxyAgent;
opts.agent = new HttpsProxyAgent(proxy, ...);

Since the constructor is only available as default.HttpsProxyAgent, the named lookup returns undefined, and the next new throws.

#26361 is still useful because it pre-injects an agent for the main GoogleGenAI auth path, causing gaxios to skip the lazy dynamic import. But any dependency-created or auth-library-created gaxios instance without an explicit agent can still reach the broken bundled fallback.

A possible Gemini-side fix would be to normalize the bundled proxy-agent module shape, for example with an esbuild alias shim that re-exports stable named ESM exports for https-proxy-agent and http-proxy-agent, plus a bundle-level regression test asserting that the generated dynamic import exposes a constructable named HttpsProxyAgent.

Related:

Related note: there is also a google-auth-library transporter propagation issue tracked separately in googleapis/google-cloud-node#8292, with a proposed fix in googleapis/google-cloud-node#8293. That fix can avoid this failure for specific STS helper paths by ensuring the caller-provided transporter/agent is propagated. It does not replace a Gemini-side bundle fix, because the bundled gaxios lazy proxy-agent fallback can still be reached by any path that does not receive an explicit agent.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/coreIssues related to User Interface, OS Support, Core Functionalitystatus/need-triageIssues that need to be triaged by the triage automation.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions