siyuan-note/siyuan · error
URL has no host
Error message
URL has no host
What it means
Returned by HTTPRequest when url.Parse succeeds and the scheme is http/https, but u.Host is empty. This catches scheme-prefixed but hostless inputs like 'http:///path', 'https://?q=1', or 'http:path' that parse cleanly yet have no authority component.
Source
Thrown at kernel/util/httprequest.go:66
// 与 SSRFSafeDialer 共用 isPrivateIP,覆盖 NAT64、6to4、Teredo 等 IPv6 过渡地址。
if isPrivateIP(ip) {
return errors.New("access to private/internal IP is prohibited")
}
}
return nil
}
// HTTPRequest 发起一次通用 HTTP 调用,供智能体 http_request 工具使用。
// 与 WebFetch 不同:本函数不做 HTML→Markdown 转换,文本类响应(含 JSON/XML)原样返回,
// 便于智能体直接消费 REST API 的 JSON 输出。method 取值:GET/POST/PUT/DELETE/PATCH。
// 返回的 text 为响应正文(文本类)或落盘后的文件路径(二进制类)。
func HTTPRequest(method, rawURL string, headers map[string]string, body string) (statusCode int, contentType string, text string, err error) {
u, err := url.Parse(rawURL)
if err != nil || (u.Scheme != "http" && u.Scheme != "https") {
return 0, "", "", errors.New("URL must start with http:// or https://")
}
if u.Host == "" {
return 0, "", "", errors.New("URL has no host")
}
if serr := CheckHostSSRF(u.Hostname()); serr != nil {
return 0, "", "", serr
}
method = strings.ToUpper(strings.TrimSpace(method))
if method == "" {
method = "GET"
}
request := httpclient.NewBrowserRequest()
for k, v := range headers {
request.SetHeader(k, v)
}
if body != "" && method != "GET" && method != "HEAD" {
request.SetBody(body)
}View on GitHub (pinned to 251596fc0d)
Solutions
- Ensure the URL has a non-empty host (e.g. 'https://example.com/path') before calling HTTPRequest.
- If constructing URLs programmatically, assert u.Host != "" after url.Parse at the call site.
- Reject and re-prompt the agent/user for a complete URL.
Example fix
// before
util.HTTPRequest("GET", "http:///api/v1/status", nil, "")
// after
util.HTTPRequest("GET", "http://example.com/api/v1/status", nil, "") Defensive patterns
Strategy: validation
Validate before calling
func urlHasHost(raw string) bool {
u, err := url.Parse(raw)
return err == nil && u.Host != ""
} Prevention
- After url.Parse, assert u.Host != "" before passing to HTTPRequest.
- Build URLs from (scheme, host, path) components rather than string concatenation.
When it happens
Trigger: Calling util.HTTPRequest with a URL whose scheme is correct but which has no host — e.g. 'http:///foo', 'https://', 'http://?query', or a malformed relative URL that the parser treated as path-only.
Common situations: A URL built by joining 'https://' with an empty hostname; a copy-paste that lost the domain; an agent that stripped the host when reformatting a link.
Related errors
- URL must start with http:// or https://
- parse [u] failed: %s
- response too large
- Failed to update agent session permission
- missing query param [u]
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/9f82a6b80a581d8c.
Report an issue: GitHub.