flipped-aurora/gin-vue-admin · error
构建请求失败: %w
Error message
构建请求失败: %w
What it means
fetchPublicUpstream is a generic helper that GETs a public upstream endpoint with a timeout. This error wraps http.NewRequestWithContext failures — the HTTP request object could not be constructed, almost always because the final URL (upstreamURL(path)) is malformed (bad scheme, control characters, unparseable host).
Source
Thrown at server/mcp/http_client.go:114
timeout := global.GVA_CONFIG.MCP.RequestTimeout
if timeout <= 0 {
timeout = 15
}
return time.Duration(timeout) * time.Second
}
// defaultUpstreamTimeout 是回打主服务公共(免鉴权)接口的默认超时。
const defaultUpstreamTimeout = 10 * time.Second
// fetchPublicUpstream 回打主服务的公共(免鉴权)接口:带超时的 GET + 标准信封解析。
// 动态 tool 与编排 prompt 的注册共用同一模式,T 为信封 Data 字段的具体负载类型。
func fetchPublicUpstream[T any](path string) (*upstreamEnvelope[T], error) {
timeoutCtx, cancel := context.WithTimeout(context.Background(), defaultUpstreamTimeout)
defer cancel()
req, err := http.NewRequestWithContext(timeoutCtx, http.MethodGet, upstreamURL(path), nil)
if err != nil {
return nil, fmt.Errorf("构建请求失败: %w", err)
}
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("请求上游接口失败: %w", err)
}
defer resp.Body.Close()
rawBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("读取响应失败: %w", err)
}
if resp.StatusCode >= http.StatusBadRequest {
return nil, fmt.Errorf("上游接口返回状态码 %d: %s", resp.StatusCode, string(rawBody))
}
var result upstreamEnvelope[T]View on GitHub (pinned to 3136500ef3)
Solutions
- Inspect upstreamURL(path) — log the final URL and verify it parses (url.Parse succeeds) and has an absolute http/https scheme
- Fix the upstream base URL in the server config (no stray spaces, correct scheme/host)
- Sanitize/encode the path segment before calling fetchPublicUpstream
Example fix
// before upstreamBase := cfg.UpstreamBase // "localhost:9999" (no scheme) // after upstreamBase := "http://localhost:9999" // absolute URL with scheme
Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(upstreamURL(path))
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("invalid upstream URL %q", u)
} Type guard
func isValidUpstreamURL(raw string) bool {
u, err := url.Parse(raw)
return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
} Try / catch
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return nil, fmt.Errorf("build request failed: %w", err)
} Prevention
- Keep the upstream base URL in config as an absolute http(s) URL
- Trim whitespace/BOM from config values before building URLs
- url.Parse the composed URL once at startup as a smoke check
When it happens
Trigger: Calling any MCP tool that hits the public upstream while the configured upstream base URL is empty or invalid, or path concatenation yields an unparseable URL (spaces, newline, missing scheme).
Common situations: Missing/typo'd upstream base in config producing 'http://:8080/...' or relative URL; config value carrying whitespace or BOM; path containing unescaped characters.
Related errors
- result.Msg
- 下载结果缺少 url
- httpUrl 必须是合法的 http/https 地址
- function bucket.IsObjectExist() failed, err:
- 上游大模型流式服务返回非 2xx: status=%d content-type=%s read-body-err=%w
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/34b4146bf9632a24.
Report an issue: GitHub.