alibaba/open-code-review · error

invalid URL for %s: %w

Error message

invalid URL for %s: %w

What it means

applyProviderField validates a provider's url field with validateBaseURL and wraps any failure as "invalid URL for <key>: %w", where key is the full dotted path (e.g. providers.openai.url). Empty strings are allowed (meaning unset); anything else must parse as a valid base URL.

Source

Thrown at cmd/opencodereview/config_cmd.go:620

		}
		cfg.Llm.RetryCodes = codes
	default:
		return fmt.Errorf("unknown config key: %s\nSupported keys: %s\nProvider fields: api_key, api_key_cmd, url, protocol, model, models, auth_header, extra_body, extra_headers, retry_codes, aws_region, aws_profile\nProtocol values: anthropic, anthropic-bedrock, openai, openai-responses\nMCP server fields: type, command, args, env, url, headers, tools, setup", key, strings.Join(supportedConfigKeys, ", "))
	}
	return nil
}

func applyProviderField(providerName string, entry *ProviderEntry, field, key, value string) error {
	switch field {
	case "api_key":
		entry.APIKey = value
	case "api_key_cmd":
		entry.APIKeyCmd = value
	case "url":
		trimmedURL := strings.TrimSpace(value)
		if trimmedURL != "" {
			if err := validateBaseURL(trimmedURL); err != nil {
				return fmt.Errorf("invalid URL for %s: %w", key, err)
			}
		}
		entry.URL = trimmedURL
	case "protocol":
		normalized := llm.NormalizeProtocol(value)
		if err := llm.ValidateProtocol(normalized); err != nil {
			return err
		}
		entry.Protocol = normalized
		// Switching away from bedrock leaves aws_region/aws_profile as dead
		// config that reads as applied but nothing reads it — clear both, the
		// same way the TUI drops url/api_key/auth_header when switching onto
		// bedrock (see cpAmbientProtocol in provider_tui.go).
		if normalized != llm.ProtocolAnthropicBedrock && (entry.AWSRegion != "" || entry.AWSProfile != "") {
			fmt.Fprintf(os.Stderr, "[ocr] WARNING: clearing aws_region/aws_profile on %q: protocol %q does not use the AWS credential chain\n", providerName, normalized)
			entry.AWSRegion = ""
			entry.AWSProfile = ""
		}

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Include the scheme: `ocr config set providers.openai.url https://api.openai.com`
  2. Trim stray whitespace/quotes from the value
  3. Check the wrapped validateBaseURL message for the specific defect
  4. Leave the value empty ("" intentionally clears the URL) rather than passing a placeholder

Example fix

// before
ocr config set providers.openai.url localhost:8080
// after
ocr config set providers.openai.url http://localhost:8080
Defensive patterns

Strategy: validation

Validate before calling

u := strings.TrimSpace(url)
if u != "" {
    parsed, err := neturl.Parse(u)
    if err != nil || (parsed.Scheme != "http" && parsed.Scheme != "https") || parsed.Host == "" {
        return fmt.Errorf("provider url must include http(s):// and a host, got %q", u)
    }
}
_ = runConfigSet("providers.openai.url", u)

Try / catch

if err := runConfigSet("providers.openai.url", u); err != nil {
    if strings.Contains(err.Error(), "invalid URL for") {
        fmt.Fprintf(os.Stderr, "%q rejected: include scheme and host, e.g. https://api.example.com\n", u)
    }
}

Prevention

When it happens

Trigger: `ocr config set providers.<name>.url <value>` or the equivalent custom_providers path, with a value lacking a scheme ("localhost:8080"), containing spaces, or otherwise rejected by validateBaseURL.

Common situations: Forgetting https://; leaving a placeholder like <YOUR_URL> in a script; trailing whitespace or typos; pointing at a local gateway without the scheme.

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


AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02). Data as JSON: /api/errors/904cd814fef69c6f. Report an issue: GitHub.