{"record":{"id":"2372b882aaf3a0b5","repo":"infiniflow/ragflow","slug":"invoke-proxy-url-q-has-no-host","errorCode":null,"errorMessage":"Invoke: proxy URL %q has no host","messagePattern":"Invoke: proxy URL %q has no host","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/component/invoke.go","lineNumber":455,"sourceCode":"\treturn map[string]string{\n\t\t\"result\": \"Response body as text.\",\n\t}\n}\n\n// mustParseProxy parses a proxy URL string. We keep this helper here\n// (rather than calling url.Parse inline) so the panic-on-bad-input\n// behavior is uniform across the package — proxy strings are operator-\n// configured, a malformed one is a deployment error worth crashing\n// loud on.\nfunc mustParseProxy(raw string) *url.URL {\n\tu, err := url.Parse(raw)\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"Invoke: invalid proxy URL %q: %v\", raw, err))\n\t}\n\t// Defensive check: net/http.ProxyURL will silently no-op on a\n\t// URL with no Host. Surface a clear panic instead.\n\tif u.Host == \"\" {\n\t\tpanic(fmt.Sprintf(\"Invoke: proxy URL %q has no host\", raw))\n\t}\n\treturn u\n}\n\n// stripHTMLTags removes HTML tags from the input string. This is a\n// best-effort implementation — it uses a simple regexp to remove\n// everything between < and >. It is NOT a full HTML sanitizer and\n// should only be used for cleaning up response text for consumption\n// by downstream LLM nodes.\n// Mirrors Python's `strip_html_tags` helper (invoke.py).\nfunc stripHTMLTags(s string) string {\n\t// Simple regexp-based approach: remove everything between < and >\n\tre := strings.NewReplacer(\n\t\t\"<script\", \"\\n<script\",\n\t\t\"</script>\", \"</script>\\n\",\n\t\t\"<style\", \"\\n<style\",\n\t\t\"</style>\", \"</style>\\n\",\n\t)","sourceCodeStart":437,"sourceCodeEnd":473,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/internal/agent/component/invoke.go#L437-L473","documentation":"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://\".","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nproxy: \"http://\"  // panic: Invoke: proxy URL \"http://\" has no host\n\n// after\nproxy: \"http://proxy.example.com:8080\"","handlingStrategy":"validation","validationCode":"u, err := url.Parse(raw)\nif err != nil || u.Host == \"\" {\n    return fmt.Errorf(\"proxy URL %q is not a valid absolute URL with host\", raw)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["go","proxy","invoke","configuration","panic","url-parsing"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}