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
- Set a complete proxy URL including host, e.g. http://proxy.example.com:8080
- If the host comes from an env var/secret, verify it is actually populated before the workflow starts
- Check the %q-formatted value in the panic message to see exactly what was parsed
- 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
- Assert both url.Parse succeeds and the parsed URL has a non-empty Host
- Fail fast when proxy env vars/secrets are unset or contain unsubstituted placeholders
- Use full scheme://host:port proxy strings from a vetted config library
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
- Invoke: invalid proxy URL %q: %v
- Invalid Moodle API response
- failed to initialize logger: {err}
- ListOperations: nth requires n to be within the valid range
- ListOperations: head requires n to be within the valid range
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/2372b882aaf3a0b5.
Report an issue: GitHub.