infiniflow/ragflow · error

Invoke: proxy URL %q has no host

Error message

Invoke: proxy URL %q has no host

What it means

mustParseProxy panics when the proxy string parses successfully but contains no host (u.Host == ""). This is a deliberate defensive check because net/http.ProxyURL silently no-ops on a hostless URL — the component authors chose a loud panic over silent proxy bypass. Typical inputs are empty-ish strings like "http://", ":8080", or "socks5://".

Source

Thrown at internal/agent/component/invoke.go:455

	return map[string]string{
		"result": "Response body as text.",
	}
}

// mustParseProxy parses a proxy URL string. We keep this helper here
// (rather than calling url.Parse inline) so the panic-on-bad-input
// behavior is uniform across the package — proxy strings are operator-
// configured, a malformed one is a deployment error worth crashing
// loud on.
func mustParseProxy(raw string) *url.URL {
	u, err := url.Parse(raw)
	if err != nil {
		panic(fmt.Sprintf("Invoke: invalid proxy URL %q: %v", raw, err))
	}
	// Defensive check: net/http.ProxyURL will silently no-op on a
	// URL with no Host. Surface a clear panic instead.
	if u.Host == "" {
		panic(fmt.Sprintf("Invoke: proxy URL %q has no host", raw))
	}
	return u
}

// stripHTMLTags removes HTML tags from the input string. This is a
// best-effort implementation — it uses a simple regexp to remove
// everything between < and >. It is NOT a full HTML sanitizer and
// should only be used for cleaning up response text for consumption
// by downstream LLM nodes.
// Mirrors Python's `strip_html_tags` helper (invoke.py).
func stripHTMLTags(s string) string {
	// Simple regexp-based approach: remove everything between < and >
	re := strings.NewReplacer(
		"<script", "\n<script",
		"</script>", "</script>\n",
		"<style", "\n<style",
		"</style>", "</style>\n",
	)

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Set a complete proxy URL including host, e.g. http://proxy.example.com:8080
  2. If the host comes from an env var/secret, verify it is actually populated before the workflow starts
  3. Check the %q-formatted value in the panic message to see exactly what was parsed
  4. Add a pre-deploy assertion that url.Parse(raw).Host is non-empty for every configured proxy

Example fix

// before
proxy: "http://"  // panic: Invoke: proxy URL "http://" has no host

// after
proxy: "http://proxy.example.com:8080"
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(raw)
if err != nil || u.Host == "" {
    return fmt.Errorf("proxy URL %q is not a valid absolute URL with host", raw)
}

Prevention

When it happens

Trigger: Setting the Invoke component's proxy to a scheme-only URL ("https://"), a URL where only a port or path is given (":8080", "/proxy"), or a value whose host was dropped during templating; mustParseProxy is called and u.Host is empty.

Common situations: Env-var or secret placeholder not substituted (e.g. literal "http://${PROXY_HOST}" left unset yields hostless input after templating failure), copy-paste that lost the hostname, config where only the scheme was filled in.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/2372b882aaf3a0b5. Report an issue: GitHub.