Tencent/WeKnora · error
invalid URL: %w
Error message
invalid URL: %w
What it means
This error is returned by the RSS client's fetch when the raw URL string cannot be parsed by net/url.Parse. Note that url.Parse is very lenient; this only fires for genuinely malformed URL syntax (e.g. control characters, invalid percent-escapes like %zz, or a bare colon in the first path segment). By the time this line runs, SSRF validation has already passed, so this is the last URL-syntax gate before the HTTP request is built.
Source
Thrown at internal/datasource/connector/rss/client.go:53
func newClient(headers map[string]string) *client {
cfg := utils.DefaultSSRFSafeHTTPClientConfig()
cfg.Timeout = requestTimeout
return &client{
httpClient: utils.NewSSRFSafeHTTPClient(cfg),
headers: headers,
}
}
// fetch retrieves rawURL with SSRF validation and size limiting. Custom auth
// headers are only attached when withAuthHeaders is true (feed fetches); article
// pages on third-party domains must not receive feed credentials.
func (c *client) fetch(ctx context.Context, rawURL string, maxSize int64, withAuthHeaders bool) ([]byte, error) {
if err := utils.ValidateURLForSSRF(rawURL); err != nil {
return nil, fmt.Errorf("URL rejected: %w", err)
}
if _, err := url.Parse(rawURL); err != nil {
return nil, fmt.Errorf("invalid URL: %w", err)
}
ctx, cancel := context.WithTimeout(ctx, requestTimeout)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, rawURL, nil)
if err != nil {
return nil, err
}
if withAuthHeaders {
for k, v := range c.headers {
req.Header.Set(k, v)
}
}
if req.Header.Get("User-Agent") == "" {
req.Header.Set("User-Agent", defaultUserAgent)
}View on GitHub (pinned to 988cbb0330)
Solutions
- Print the URL with %q and check for control characters, whitespace, or invalid %-escapes; trim and re-enter the feed URL in the datasource config.
- Percent-encode the offending characters (e.g. use url.PathEscape on path components, or strings.TrimSpace on pasted values) before saving the config.
- If the URL comes from user input, validate at ingestion time with url.ParseRequestURI and reject/mend it there instead of failing at fetch time.
Example fix
// before
data, err := cli.fetchFeed(ctx, feedURL)
// after
trimmed := strings.TrimSpace(feedURL)
if _, perr := url.Parse(trimmed); perr != nil {
return fmt.Errorf("configured feed URL is malformed: %w", perr)
}
data, err := cli.fetchFeed(ctx, trimmed) Defensive patterns
Strategy: validation
Validate before calling
func validFeedURL(raw string) error {
trimmed := strings.TrimSpace(raw)
if trimmed == "" {
return errors.New("empty feed URL")
}
u, err := url.Parse(trimmed)
if err != nil {
return fmt.Errorf("malformed URL: %w", err)
}
if u.Scheme != "http" && u.Scheme != "https" {
return fmt.Errorf("unsupported scheme %q", u.Scheme)
}
return nil
} Prevention
- Trim and normalize pasted URLs (strip whitespace, smart quotes) at config ingestion time.
- Always specify scheme explicitly (https://) instead of relying on defaults.
- Unit-test feed URL lists with url.Parse before saving datasource config.
- Reject URLs containing control characters with a strings.ContainsFunc check.
When it happens
Trigger: A feed URL or article URL stored in the datasource config contains characters that net/url rejects: invalid percent-encoding sequences (e.g. "https://example.com/feed%zz"), ASCII control characters or unescaped spaces/newlines pasted into the URL field, or a first path segment containing a colon (e.g. "https://example.com/foo:bar").
Common situations: Admins paste feed URLs from emails/docs with trailing whitespace or smart quotes; URLs built by string concatenation with unescaped user input; migrations import feed lists from CSV where a comma or newline slipped into the URL cell.
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
- ErrInvalidConfig
- sandbox: docker client requires a config
- sandbox: docker backend requires an image
- e2b remote client config is required
- E2BAPIKey is required for the E2B backend
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/2a0036dd77fbbd7d.
Report an issue: GitHub.