github/copilot-sdk · error

SessionFS.SessionStatePath is required

Error message

SessionFS.SessionStatePath is required

What it means

validateSessionFSConfig requires SessionFS.SessionStatePath to be a non-empty string when constructing a Client. The session state path is where the provider persists session state, so without it the SessionFS provider cannot be configured. NewClient fails fast with this error rather than starting with a half-configured filesystem session.

Solutions

  1. Set config.SessionFS.SessionStatePath to an absolute writable file path before calling NewClient
  2. Derive it from an existing config value, e.g. filepath.Join(dir, "session-state.json")
  3. Add a pre-construction validation step in your own code that asserts the path is non-empty

Example fix

// before
client, err := copilot.NewClient(cfg) // cfg.SessionFS.SessionStatePath == ""
// after
cfg.SessionFS.SessionStatePath = filepath.Join(dataDir, "copilot-session-state.json")
client, err := copilot.NewClient(cfg)
Defensive patterns

Strategy: validation

Validate before calling

if cfg.SessionFS != nil && cfg.SessionFS.SessionStatePath == "" {
    return fmt.Errorf("config error: SessionFS.SessionStatePath must be set")
}

Prevention

When it happens

Trigger: Calling NewClient with a Config whose SessionFS is non-nil but has SessionStatePath set to "" (or left unset).

Common situations: Structuring the SessionFS config field-by-field and forgetting SessionStatePath; constructing Config dynamically from env/flags where the state-path variable is empty; copying a config struct and dropping one field.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at go/client.go:90

		if providers[i].BearerTokenProvider != nil {
			callbacks[providers[i].Name] = providers[i].BearerTokenProvider
		}
	}
	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) {

View on GitHub (pinned to cd8cf15dc3)