github/copilot-sdk · error
Invalid URIConnection format
Error message
Invalid URIConnection format: %s
What it means
parseCLIURL in go/client.go parses the URIConnection URL passed to NewClient. When the URL looks like a bracketed host:port ([v6]:port) it validates that the host is a valid IPv6 address; if netip.ParseAddr fails or the address is not IPv6, it panics with this message. The library only accepts IPv6 literal hosts in the bracketed form, so any other host form here is rejected.
Solutions
- Use an IPv6 literal inside brackets, e.g. "http://[::1]:3000"
- Use the plain host:port form without brackets for IPv4/hostname, e.g. "http://localhost:3000"
- Pass only a port (e.g. ":3000" or the port string) to default to localhost
- Log/print the exact URL string before NewClient to spot bracket or colon mistakes
Example fix
// before
client := NewClient("http://[myhost]:3000")
// after
client := NewClient("http://localhost:3000") // or "http://[::1]:3000" for IPv6 Defensive patterns
Strategy: validation
Validate before calling
func validCLIURL(u string) bool {
host, port, err := net.SplitHostPort(u)
if err != nil {
return false
}
if strings.HasPrefix(u, "[") {
addr, err := netip.ParseAddr(host)
return err == nil && addr.Is6()
}
_, err = strconv.Atoi(port)
return err == nil
} Type guard
func isIPv6Literal(host string) bool {
addr, err := netip.ParseAddr(host)
return err == nil && addr.Is6()
} Prevention
- Never put hostnames or IPv4 inside brackets; brackets are only for IPv6 literals
- Prefer plain host:port URLs like http://localhost:PORT
- Sanitize environment-provided URLs before passing to NewClient
- Write a table test covering IPv6, IPv4, hostname, and port-only forms
When it happens
Trigger: Calling NewClient with a CLI URL like "http://[hostname]:3000" or "[::1:notanumber]" where SplitHostPort succeeds (bracketed form) but the host inside brackets is not a valid IPv6 literal (e.g. a DNS name, IPv4, or malformed address).
Common situations: Developers put a hostname or IPv4 address inside brackets instead of an IPv6 literal, or hand-build the URL string with typos (missing/extra colons), or an environment variable containing the server URL was set to a non-IPv6 bracketed value.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Invalid port in URIConnection
- Invalid cli_url format
- Env is not supported with InProcessConnection: the…
- WorkingDirectory is not supported with InProcessConnection…
- Telemetry is not supported with InProcessConnection…
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/fad8ada5ae86f1a7.
Report an issue: GitHub.
Appendix: source
Thrown at go/client.go:421
// parseCLIURL parses a CLI URL into host and port components.
//
// Supports formats: "host:port", "[ipv6]:port", "http://host:port", "https://host:port", or just "port".
// Panics if the URL format is invalid or the port is out of range.
func parseCLIURL(url string) (string, int) {
// Remove protocol if present
cleanURL, _ := strings.CutPrefix(url, "https://")
cleanURL, _ = strings.CutPrefix(cleanURL, "http://")
// Use the standard parser only for the bracketed IPv6 form. Keep the
// existing host:port parsing behavior for all other inputs.
if strings.HasPrefix(cleanURL, "[") {
host, portStr, err := net.SplitHostPort(cleanURL)
if err != nil {
panic(fmt.Sprintf("Invalid port in URIConnection: %s", url))
}
addr, err := netip.ParseAddr(host)
if err != nil || !addr.Is6() {
panic(fmt.Sprintf("Invalid URIConnection format: %s", url))
}
port, err := strconv.Atoi(portStr)
if err != nil || port <= 0 || port > 65535 {
panic(fmt.Sprintf("Invalid port in URIConnection: %s", url))
}
return host, port
}
// Parse host:port or port format
var host string
var portStr string
if before, after, found := strings.Cut(cleanURL, ":"); found {
host = before
portStr = after
} else {
portStr = cleanURL
}
View on GitHub (pinned to cd8cf15dc3)