github/copilot-sdk · critical

Env is not supported with InProcessConnection: the…

Error message

Env is not supported with InProcessConnection: the in-process transport loads the native runtime into the shared host process, whose single environment block cannot carry per-client values. Set the variables on the host process environment instead.

What it means

NewClient validates ClientOptions against the chosen RuntimeConnection. The in-process transport loads the native runtime into the host process, so a single shared environment block cannot carry per-client values; setting opts.Env (and likewise WorkingDirectory/Telemetry) with InProcessConnection panics immediately at construction time. The fix is to set those variables on the host process environment or use a child-process transport.

Solutions

  1. Remove the Env option and set the variables on the host process environment before NewClient
  2. Or switch to a child-process connection which owns its OS process and supports per-connection env
  3. If you also set WorkingDirectory or Telemetry, move those to the host process/env as well
  4. Split option sets per transport type so in-process clients never receive env/telemetry options

Example fix

// before
client, err := NewClient(ctx, InProcessConnection{},
    WithEnv([]string{"DEBUG=1"})) // panics
// after
os.Setenv("DEBUG", "1")
client, err := NewClient(ctx, InProcessConnection{})
Defensive patterns

Strategy: validation

Validate before calling

func newInProcessClient(ctx context.Context, opts ...ClientOption) (*Client, error) {
    for _, o := range opts {
        if isEnvOption(o) {
            return nil, errors.New("Env is not supported with InProcessConnection")
        }
    }
    return NewClient(ctx, InProcessConnection{}, opts...)
}

Type guard

func isChildProcess(c RuntimeConnection) bool {
    _, ok := c.(InProcessConnection)
    return !ok // env options only safe when not in-process
}

Try / catch

func() (c *Client) {
    defer func() {
        if r := recover(); r != nil {
            log.Fatalf("invalid client options: %v", r)
        }
    }()
    c, _ = NewClient(ctx, InProcessConnection{}, opts...)
    return
}()

Prevention

When it happens

Trigger: Calling NewClient with an InProcessConnection while passing WithEnv-style options in ClientOptions (opts.Env != nil) — panics synchronously inside validateEnvironmentOptions.

Common situations: Reusing client option helpers written for the child-process transport when switching to in-process; configuring per-client env in tests that embed the runtime; copying setup code that assumed process isolation.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/de754060b6c559cf. Report an issue: GitHub.

Appendix: source

Thrown at go/client.go:111

		return errors.New("SessionFS.Conventions must be either 'posix' or 'windows'")
	}
	return nil
}

// validateEnvironmentOptions enforces the transport-specific rules for
// per-client environment, working directory, and telemetry. It panics (fails
// loud) on a misconfiguration, matching the other SDKs.
//
// The in-process transport loads the native runtime into this process, whose
// single environment block and process-global working directory cannot carry
// per-client values, and whose telemetry lowers to shared process-global env
// vars — so options that depend on them are rejected there. Child-process
// transports each own their OS process, so per-connection env is allowed, but
// setting it in both the client-level option and the connection is rejected.
func validateEnvironmentOptions(connection RuntimeConnection, opts *ClientOptions) {
	if _, ok := connection.(InProcessConnection); ok {
		if opts.Env != nil {
			panic("Env is not supported with InProcessConnection: the in-process transport loads the native runtime into the shared host process, whose single environment block cannot carry per-client values. Set the variables on the host process environment instead.")
		}
		if opts.WorkingDirectory != "" {
			panic("WorkingDirectory is not supported with InProcessConnection: the native runtime shares the host process working directory. Use a child-process transport, or set the process working directory before creating the client.")
		}
		if opts.Telemetry != nil {
			panic("Telemetry is not supported with InProcessConnection: telemetry configuration is lowered to environment variables read by native runtime code running in the shared host process, so per-client telemetry cannot be honored in-process. Configure telemetry via the host process environment, or use a child-process transport.")
		}
		return
	}

	if cp, ok := connection.(childProcessConnection); ok {
		if cp.connEnv() != nil && opts.Env != nil {
			panic("Set environment variables via either the client-level Env option or the connection's Env, not both. Prefer the connection-level Env for child-process transports.")
		}
	}
}

// Client manages the connection to the Copilot CLI server and provides session management.

View on GitHub (pinned to cd8cf15dc3)