github/copilot-sdk · error

SessionFS.Conventions must be either 'posix' or 'windows'

Error message

SessionFS.Conventions must be either 'posix' or 'windows'

What it means

SessionFS.Conventions must be exactly rpc.SessionFSSetProviderConventionsPosix or ...Windows. The library needs to know the path-separator convention of the filesystem provider, and any other value (including the zero value) is rejected by validateSessionFSConfig.

Solutions

  1. Set config.SessionFS.Conventions = rpc.SessionFSSetProviderConventionsPosix (or ...Windows) explicitly
  2. Always use the rpc constants rather than raw string literals
  3. Choose based on the host OS of the session, e.g. runtime.GOOS == "windows"

Example fix

// before
cfg.SessionFS.Conventions = "posix" // or zero value
// after
if runtime.GOOS == "windows" {
    cfg.SessionFS.Conventions = rpc.SessionFSSetProviderConventionsWindows
} else {
    cfg.SessionFS.Conventions = rpc.SessionFSSetProviderConventionsPosix
}
Defensive patterns

Strategy: validation

Validate before calling

switch cfg.SessionFS.Conventions {
case rpc.SessionFSSetProviderConventionsPosix, rpc.SessionFSSetProviderConventionsWindows:
    // ok
default:
    return fmt.Errorf("config error: SessionFS.Conventions must be posix or windows")
}

Prevention

When it happens

Trigger: Calling NewClient with SessionFS.Conventions left as the zero value, a lowercase custom string, or a typo'd constant.

Common situations: Initializing the Config struct without setting Conventions; hand-writing the string "posix" instead of using the rpc constant; cross-platform code defaulting incorrectly on one OS.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at go/client.go:93

	}
	if len(callbacks) == 0 {
		return nil
	}
	return callbacks
}

func validateSessionFSConfig(config *SessionFSConfig) error {
	if config == nil {
		return nil
	}
	if config.InitialWorkingDirectory == "" {
		return errors.New("SessionFS.InitialWorkingDirectory is required")
	}
	if config.SessionStatePath == "" {
		return errors.New("SessionFS.SessionStatePath is required")
	}
	if config.Conventions != rpc.SessionFSSetProviderConventionsPosix && config.Conventions != rpc.SessionFSSetProviderConventionsWindows {
		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.")

View on GitHub (pinned to cd8cf15dc3)