multica-ai/multica · error
invalid MULTICA_SERVER_URL: %w
Error message
invalid MULTICA_SERVER_URL: %w
What it means
NormalizeServerBaseURL failed at the first step: url.Parse rejected the trimmed MULTICA_SERVER_URL value. The Go URL parser is lenient, so this only happens with genuinely malformed input (control characters, an unmatched '%' escape, or embedded whitespace that survives trimming at the ends). The error wraps the parse error so the exact position is visible.
Source
Thrown at server/internal/daemon/config.go:579
// isOfficialCloudServer reports whether the resolved server base URL points
// at Multica's hosted cloud. Used to pick the auto-update default: cloud
// users run a server that publishes the matching CLI release, so opt-in
// self-update is safe; self-host users may run a fork or pin to an older
// server, so the default flips to off. Matching is host-only and
// case-insensitive — port and path are ignored.
func isOfficialCloudServer(baseURL string) bool {
u, err := url.Parse(strings.TrimSpace(baseURL))
if err != nil {
return false
}
return strings.EqualFold(u.Hostname(), officialCloudHost)
}
// NormalizeServerBaseURL converts a WebSocket or HTTP URL to a base HTTP URL.
func NormalizeServerBaseURL(raw string) (string, error) {
u, err := url.Parse(strings.TrimSpace(raw))
if err != nil {
return "", fmt.Errorf("invalid MULTICA_SERVER_URL: %w", err)
}
switch u.Scheme {
case "ws":
u.Scheme = "http"
case "wss":
u.Scheme = "https"
case "http", "https":
default:
return "", fmt.Errorf("MULTICA_SERVER_URL must use ws, wss, http, or https")
}
if u.Path == "/ws" {
u.Path = ""
}
u.RawPath = ""
u.RawQuery = ""
u.Fragment = ""
return strings.TrimRight(u.String(), "/"), nil
}View on GitHub (pinned to 2c0912b6ec)
Solutions
- Print the value with %q to reveal invisible characters: it usually shows a quote, control rune, or raw %
- Re-enter the URL as plain https://host[:port] with no quotes or escapes inside the value
- URL-encode any legitimate special characters (a '%' must be '%25')
Defensive patterns
Strategy: validation
Validate before calling
// Validate the env var before passing it on.
raw := strings.TrimSpace(os.Getenv("MULTICA_SERVER_URL"))
if u, err := url.Parse(raw); err != nil {
return fmt.Errorf("MULTICA_SERVER_URL %q is not a parseable URL: %w", raw, err)
} Try / catch
Handle at config-load time: catch the error, echo the raw value with %q so hidden characters are visible, and prompt the user to re-enter it.
Prevention
- Avoid pasting URLs from rich-text sources
- URL-encode special characters ('%' as '%25')
- Lint env files for control characters in CI
When it happens
Trigger: Setting MULTICA_SERVER_URL to a value containing a raw '%' (e.g. a password with %zz in it), control characters from a copy-paste, or a trailing/leading quote from shell wrapping. Note that values like 'localhost:8080' parse fine and instead fail the scheme check (error 872).
Common situations: Copy-paste from docs with smart quotes/invisible characters, shell quoting mistakes leaving a stray quote inside the value, secrets or malformed escapes embedded in the URL.
Related errors
- MULTICA_SERVER_URL must use ws, wss, http, or https
- invalid %s: %w
- %w: %s
- no agent CLI found: install claude, codebuddy, codex, copilo
- Invalid desktop runtime config: ${field} must be a non-empty
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/025373e8a8b44b00.
Report an issue: GitHub.