github/copilot-sdk · error
unknown RuntimeConnection type: %T
Error message
unknown RuntimeConnection type: %T
What it means
NewClient panics when the Connection option implements RuntimeConnection with a type the SDK does not recognize. The connection switch in NewClient handles StdioConnection, TCPConnection, URIConnection and InProcessConnection; anything else falls to the default branch. This is almost always a custom connection type or a value that does not actually implement the intended interface.
Solutions
- Use one of the supported connection types: StdioConnection, TCPConnection, URIConnection, or InProcessConnection.
- Remove custom wrappers; configure behavior via ClientOptions instead.
- Check the %T value in the panic message against the SDK's exported connection types after upgrading.
Example fix
// before
client := clientpkg.NewClient(&clientpkg.Options{Connection: myLoggingConn{inner: clientpkg.StdioConnection{}}})
// after
client := clientpkg.NewClient(&clientpkg.Options{
Connection: clientpkg.StdioConnection{},
// custom behavior via options/hooks instead of a wrapper type
}) Defensive patterns
Strategy: type-guard
Validate before calling
switch c := opts.Connection.(type) {
case clientpkg.StdioConnection, clientpkg.TCPConnection, clientpkg.URIConnection, clientpkg.InProcessConnection:
// ok
case nil:
// default transport
default:
return fmt.Errorf("unsupported connection type %T", c)
} Type guard
func isSupportedConnection(c clientpkg.RuntimeConnection) bool {
switch c.(type) {
case clientpkg.StdioConnection, clientpkg.TCPConnection, clientpkg.URIConnection, clientpkg.InProcessConnection:
return true
}
return false
} Prevention
- Only use the SDK's exported connection types.
- Re-check custom wrappers after SDK upgrades for dropped interface cases.
- Beware typed-nil pointers implementing interfaces; pass concrete values.
When it happens
Trigger: Passing a user-defined struct (or a wrongly-typed value, e.g. *MyConn vs MyConn, or a nil typed pointer) as Options.Connection so it satisfies RuntimeConnection but matches no known case. Panic at go/client.go:286 with the Go type in the message (%T).
Common situations: Wrapping a connection to intercept traffic; upgrading the SDK where an older custom connection type is no longer a recognized case; passing nil interface vs typed nil confusion.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- URIConnection requires a non-empty URL
- GitHubToken and UseLoggedInUser cannot be used with…
- failed to connect to CLI server at
- Env is not supported with InProcessConnection: the…
- WorkingDirectory is not supported with InProcessConnection…
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/8cd67efb859a3524.
Report an issue: GitHub.
Appendix: source
Thrown at go/client.go:286
client.cliArgs = append([]string{}, conn.Args...)
}
client.port = conn.Port
client.tcpConnectionToken = conn.ConnectionToken
case URIConnection:
if conn.URL == "" {
panic("URIConnection requires a non-empty URL")
}
host, port := parseCLIURL(conn.URL)
client.actualHost = host
client.actualPort = port
client.isExternalServer = true
client.useStdio = false
client.tcpConnectionToken = conn.ConnectionToken
case InProcessConnection:
client.useStdio = false
client.useInProcess = true
default:
panic(fmt.Sprintf("unknown RuntimeConnection type: %T", connection))
}
// Validate transport-specific option constraints (fail loud). The in-process
// transport loads the runtime into this process, whose single environment
// block, process-global working directory, and shared telemetry state cannot
// carry per-client values. Child-process transports may set env via either
// the client-level option or the connection, but not both.
validateEnvironmentOptions(connection, &opts)
// Validate auth options when connecting to an external runtime.
if client.isExternalServer && (opts.GitHubToken != "" || opts.UseLoggedInUser != nil) {
panic("GitHubToken and UseLoggedInUser cannot be used with URIConnection (external runtime manages its own auth)")
}
// For child-process transports, a connection-level env takes precedence over
// the client-level env (setting both was rejected above). Resolve it before
// defaulting so an explicit empty connection env stays authoritative.
if cp, ok := connection.(childProcessConnection); ok {View on GitHub (pinned to cd8cf15dc3)