Tencent/WeKnora · error
invalid api_base_url: %w
Error message
invalid api_base_url: %w
What it means
Feishu's validateAPIBaseURL allows a custom api_base_url for private deployments, but first parses it with url.Parse. This error wraps any url.Parse failure, meaning the configured api_base_url is not a syntactically valid URL.
Source
Thrown at internal/im/feishu/adapter.go:100
appID: appID,
appSecret: appSecret,
verificationToken: verificationToken,
encryptKey: encryptKey,
apiBaseURL: apiBaseURL,
}, nil
}
// validateAPIBaseURL checks that a custom Feishu/Lark API base URL uses an
// http(s) scheme and passes SSRF validation. Empty or the region default is
// allowed without further checks. Mirrors wecom.validateEndpointURL but allows
// plain http for internal-network reverse proxies that terminate TLS at nginx.
func validateAPIBaseURL(endpoint, defaultEndpoint string) error {
if endpoint == "" || endpoint == defaultEndpoint {
return nil
}
u, err := url.Parse(endpoint)
if err != nil {
return fmt.Errorf("invalid api_base_url: %w", err)
}
if u.Scheme != "http" && u.Scheme != "https" {
return fmt.Errorf("api_base_url must use http(s):// scheme, got %s://", u.Scheme)
}
if err := utils.ValidateURLForSSRF(endpoint); err != nil {
return fmt.Errorf("%w (for private deployments on internal networks, add the hostname to SSRF_WHITELIST)", err)
}
return nil
}
// api builds an Open Platform API URL on this adapter's cloud. path is a format
// string beginning with "/open-apis/"; args fill its verbs.
func (a *Adapter) api(path string, args ...any) string {
return a.apiBaseURL + fmt.Sprintf(path, args...)
}
// startStreamReaper starts a background goroutine (once) that periodically
// removes orphaned stream entries from feishuStreams. This prevents memoryView on GitHub (pinned to 988cbb0330)
Solutions
- Fix the wrapped url.Parse error — validate the string with net/url.Parse in a quick test to see the exact problem.
- Re-enter the api_base_url cleanly, e.g. https://open.feishu.internal, without quotes or stray whitespace.
- Leave api_base_url empty to use the default endpoint if a custom one isn't actually needed.
Example fix
// before api_base_url: "https://open.feishu.cn/%zz" // after api_base_url: "https://open.feishu.cn"
Defensive patterns
Strategy: validation
Validate before calling
if endpoint != "" {
if _, err := url.Parse(endpoint); err != nil {
return fmt.Errorf("api_base_url is not a valid URL: %w", err)
}
} Type guard
func isParseableURL(s string) bool { _, err := url.Parse(s); return err == nil } Try / catch
if err := validateAPIBaseURL(endpoint, defaultEndpoint); err != nil {
if strings.HasPrefix(err.Error(), "invalid api_base_url") {
return fmt.Errorf("fix api_base_url syntax: %w", err)
}
return err
} Prevention
- Trim whitespace and quotes from config-provided URLs before storing.
- Test custom endpoints with url.Parse in a preflight check.
- Leave api_base_url empty when the default endpoint suffices.
- Check for stray characters introduced by shell or env escaping.
When it happens
Trigger: NewAdapter called with a custom endpoint (non-empty and different from the default) that url.Parse rejects — e.g. containing invalid characters, a bare '%' or malformed percent-encoding, or control characters.
Common situations: Copy-pasting a URL with trailing spaces/quotes or invisible characters; missing scheme typos that produce unparseable input; shell/env escaping introducing stray characters.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- create verification request failed: %w
- api_base_url must use http(s):// scheme, got %s://
- failed to create Exa request: %w
- failed to create Metaso request: %w
- sandbox: config is missing required fields
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/1d70661d136b9edc.
Report an issue: GitHub.