chenhg5/cc-connect · error

providerproxy: parse target: %w

Error message

providerproxy: parse target: %w

What it means

`NewProviderProxy` parses the upstream API base URL before starting a local reverse proxy; if `url.Parse` fails on the trimmed target, it returns `providerproxy: parse target: %w`. This means the configured ANTHROPIC_BASE_URL-style target is not a parsable URL, so no proxy can be started.

Source

Thrown at core/providerproxy.go:39

// Some providers (e.g. SiliconFlow) don't support thinking.type "adaptive"
// sent by Claude Code 2.x. The proxy rewrites the thinking field to
// the configured override value before forwarding.
type ProviderProxy struct {
	targetURL        string
	thinkingOverride string
	listener         net.Listener
	server           *http.Server
	once             sync.Once
}

// NewProviderProxy creates and starts a local reverse proxy for the
// given upstream URL. thinkingOverride controls what thinking.type to
// rewrite "adaptive" to (e.g. "disabled" or "enabled").
// Returns the local URL to use as ANTHROPIC_BASE_URL.
func NewProviderProxy(targetURL, thinkingOverride string) (*ProviderProxy, string, error) {
	target, err := url.Parse(strings.TrimRight(targetURL, "/"))
	if err != nil {
		return nil, "", fmt.Errorf("providerproxy: parse target: %w", err)
	}

	listener, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		return nil, "", fmt.Errorf("providerproxy: listen: %w", err)
	}

	proxy := httputil.NewSingleHostReverseProxy(target)
	origDirector := proxy.Director
	proxy.Director = func(req *http.Request) {
		origDirector(req)
		req.Host = target.Host
	}
	proxy.FlushInterval = -1 // flush SSE events immediately

	override := thinkingOverride
	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Print the exact targetURL being passed and inspect it for typos or invisible characters.
  2. Fix the base_url value in config.toml (must be a valid absolute URL, e.g. https://api.example.com).
  3. Validate before use: `u, err := url.Parse(strings.TrimRight(cfg.BaseURL, "/")); err != nil { ... }`.
  4. Re-export the environment variable if the value came from env and looks corrupted.

Example fix

// before
baseURL := os.Getenv("ANTHROPIC_BASE_URL")
proxy, local, err := NewProviderProxy(baseURL, "disabled")

// after
baseURL := strings.TrimSpace(os.Getenv("ANTHROPIC_BASE_URL"))
if u, err := url.Parse(baseURL); err != nil || u.Scheme == "" || u.Host == "" {
    return fmt.Errorf("invalid ANTHROPIC_BASE_URL %q", baseURL)
}
proxy, local, err := NewProviderProxy(baseURL, "disabled")
Defensive patterns

Strategy: validation

Validate before calling

func validBaseURL(s string) bool {
    u, err := url.Parse(strings.TrimRight(strings.TrimSpace(s), "/"))
    return err == nil && u.Scheme != "" && u.Host != ""
}

Try / catch

proxy, local, err := NewProviderProxy(targetURL, thinking)
if err != nil {
    return fmt.Errorf("starting provider proxy for %q: %w", redactedURL, err)
}

Prevention

When it happens

Trigger: Calling NewProviderProxy (via ensureProviderProxyLocked, e.g. when enabling provider proxying for an agent) with a targetURL that fails url.Parse — missing scheme with invalid characters, stray control characters, malformed percent-escapes.

Common situations: config.toml contains a hand-edited base_url with a typo (e.g. `htp://`, embedded space, unescaped `%`); environment variable holding the base URL is corrupted; shell quoting mangled the URL.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/650b447b1b86f12e. Report an issue: GitHub.