Skip to content

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Nov 21, 2025

Description

This PR attempts to address Issue #9465. Feedback and guidance are welcome.

Problem

Users behind corporate proxies were experiencing "TypeError: fetch failed sending request" errors when using the Gemini API with Roo Code. The root cause is that the @google/genai library uses native fetch which doesn't automatically respect system proxy settings (HTTP_PROXY/HTTPS_PROXY environment variables).

Solution

  • Created a proxy-aware fetch utility that:
    • Checks for HTTP_PROXY/HTTPS_PROXY environment variables
    • Falls back to axios for proxy support when native fetch fails
    • Handles NO_PROXY settings appropriately
  • Updated the GeminiHandler constructor to setup the proxy-aware fetch before creating the GoogleGenAI client
  • The solution gracefully falls back to native fetch if proxy setup fails

Testing

  • All existing Gemini handler tests pass
  • Linting and type checking successful
  • The fix should work transparently for users both with and without proxy settings

Impact

This fix enables users behind corporate proxies to use Gemini models with Roo Code, resolving the fetch failure errors they were experiencing.

Fixes #9465

- Created proxy-aware fetch utility that respects HTTP_PROXY/HTTPS_PROXY env vars
- Falls back to axios when native fetch fails with proxy settings
- Updated GeminiHandler constructor to setup proxy-aware fetch
- This fixes the 'TypeError: fetch failed sending request' error when behind a proxy

Fixes #9465
@roomote roomote bot requested review from cte, jr and mrubens as code owners November 21, 2025 07:42
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. bug Something isn't working labels Nov 21, 2025
@roomote
Copy link
Contributor Author

roomote bot commented Nov 21, 2025

Rooviewer Clock   See task on Roo Cloud

Review completed. Found 5 issues that need attention:

  • Global fetch modification affects entire application instead of being scoped to Gemini
  • Missing https-proxy-agent package dependency in package.json
  • Unused restoreOriginalFetch import should be removed or utilized
  • Dead code: getProxyAgent function is never called
  • Broken restoreOriginalFetch implementation stores proxy fetch as "original"

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Nov 21, 2025
Comment on lines +47 to +53
// Setup proxy-aware fetch for GoogleGenAI client
// This ensures that the Gemini API client respects system proxy settings
try {
setupGlobalProxyFetch()
} catch (error) {
console.warn("Failed to setup proxy-aware fetch for Gemini:", error)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This modifies global fetch for the entire application every time a GeminiHandler is constructed, not just for Gemini API calls. If multiple GeminiHandler instances are created (which happens in testing, multi-workspace scenarios, or when users switch models), this will repeatedly overwrite global fetch. Additionally, the original fetch is never stored before the first modification, so restoreOriginalFetch() cannot actually restore it. This approach affects all fetch calls across the entire VSCode extension, potentially breaking other API providers or extension features that rely on native fetch behavior.

Fix it with Roo Code or mention @roomote and request a fix.

Comment on lines +16 to +25
// Configure HTTP agent with proxy if needed
if (httpProxy) {
try {
const HttpsProxyAgent = require("https-proxy-agent").HttpsProxyAgent
agents.httpAgent = new HttpsProxyAgent(httpProxy)
} catch (error) {
// If https-proxy-agent is not available, we'll try another approach
console.warn("https-proxy-agent not available, proxy support may be limited")
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code uses require('https-proxy-agent') but this package is not declared in dependencies or devDependencies in package.json. When users install the extension, the https-proxy-agent package will not be available, causing proxy support to silently fail with console warnings. The try-catch blocks will swallow these errors, leaving users without proxy functionality. Either add https-proxy-agent to package.json dependencies or use a different approach that doesn't require external packages.

Fix it with Roo Code or mention @roomote and request a fix.


import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
import { BaseProvider } from "./base-provider"
import { setupGlobalProxyFetch, restoreOriginalFetch } from "../../utils/proxy-fetch"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The restoreOriginalFetch function is imported but never used in this file. Since the global fetch is being modified in the constructor and there's no cleanup mechanism, this creates a permanent modification that persists throughout the application lifecycle. Either the function should be called in a destructor/cleanup method, or it should be removed from the imports if it's not needed.

Fix it with Roo Code or mention @roomote and request a fix.

Comment on lines +9 to +39
export function getProxyAgent(): { httpAgent?: http.Agent; httpsAgent?: https.Agent } {
const httpProxy = process.env.HTTP_PROXY || process.env.http_proxy
const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy
const noProxy = process.env.NO_PROXY || process.env.no_proxy

const agents: { httpAgent?: http.Agent; httpsAgent?: https.Agent } = {}

// Configure HTTP agent with proxy if needed
if (httpProxy) {
try {
const HttpsProxyAgent = require("https-proxy-agent").HttpsProxyAgent
agents.httpAgent = new HttpsProxyAgent(httpProxy)
} catch (error) {
// If https-proxy-agent is not available, we'll try another approach
console.warn("https-proxy-agent not available, proxy support may be limited")
}
}

// Configure HTTPS agent with proxy if needed
if (httpsProxy) {
try {
const HttpsProxyAgent = require("https-proxy-agent").HttpsProxyAgent
agents.httpsAgent = new HttpsProxyAgent(httpsProxy)
} catch (error) {
// If https-proxy-agent is not available, we'll try another approach
console.warn("https-proxy-agent not available, proxy support may be limited")
}
}

return agents
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getProxyAgent function is defined but never called anywhere in the codebase. This 30-line function creates HttpsProxyAgent instances that are never utilized. Either this function should be integrated into the proxy logic or removed to avoid dead code.

Fix it with Roo Code or mention @roomote and request a fix.

Comment on lines +133 to +143
export function restoreOriginalFetch(): void {
// Store original fetch if not already stored
if (!(globalThis as any).__originalFetch && globalThis.fetch) {
;(globalThis as any).__originalFetch = globalThis.fetch
}

// Restore original fetch
if ((globalThis as any).__originalFetch) {
;(globalThis as any).fetch = (globalThis as any).__originalFetch
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The restoreOriginalFetch function attempts to store the original fetch after it may have already been overwritten by setupGlobalProxyFetch. This creates a circular reference where the "original" fetch is actually the proxy fetch. The original fetch should be stored in a module-level variable before any modifications occur, not when restoreOriginalFetch is called. This breaks any attempt to restore the true native fetch implementation.

Fix it with Roo Code or mention @roomote and request a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. size:L This PR changes 100-499 lines, ignoring generated files.

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

[BUG] TypeError: fetch failed sending request for any task with Gemini

3 participants