github/copilot-sdk · error · ValueError
session_fs.session_state_path is required
Error message
session_fs.session_state_path is required
What it means
_validate_session_fs_config requires session_fs.session_state_path to be set (truthy): the path where per-session state is persisted. Without it the session filesystem cannot maintain state across calls, so construction of the client fails.
Solutions
- Set session_fs['session_state_path'] to a writable file path for session state
- Verify the value is non-empty and that the parent directory exists and is writable
- Derive it explicitly, e.g. os.path.join(base, 'session_state.json'), rather than relying on a default
- Pre-validate the session_fs dict (all three keys) before constructing CopilotClient
Example fix
// before
client = CopilotClient(session_fs={"initial_working_directory": "/workspace", "conventions": "posix"})
// after
client = CopilotClient(session_fs={
"initial_working_directory": "/workspace",
"session_state_path": "/workspace/.copilot/session_state.json",
"conventions": "posix",
}) Defensive patterns
Strategy: validation
Validate before calling
def check_session_fs(config: dict) -> None:
if not config.get("session_state_path"):
raise ValueError("session_fs.session_state_path is required") Type guard
def session_fs_is_complete(config: dict) -> bool:
return bool(config.get("initial_working_directory")) and bool(config.get("session_state_path")) and config.get("conventions") in ("posix", "windows") Try / catch
try:
client = CopilotClient(session_fs=cfg)
except ValueError as e:
if "session_state_path is required" in str(e):
cfg = {**cfg, "session_state_path": os.path.join(cfg["initial_working_directory"], "session_state.json")}
client = CopilotClient(session_fs=cfg) Prevention
- Always set session_state_path explicitly — it does not default relative to the working directory
- Derive the state path from base_directory with os.path.join so it is never omitted
- Verify the parent directory of session_state_path exists and is writable before constructing the client
- Validate all three session_fs keys together in one pre-construction check
When it happens
Trigger: Constructing CopilotClient with a session_fs dict containing initial_working_directory (and valid conventions) but no session_state_path, or with it set to an empty string/None.
Common situations: Developers copy a minimal session_fs example and add only the working directory; config templating drops the state path because it looks optional; the state path is expected to default relative to the working directory but does not.
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
- session_fs.initial_working_directory is required
- Invalid value ' '. Expected 'inprocess', 'stdio', or unset.
- gitHubToken and useLoggedInUser cannot be used with…
- sessionFs.initialCwd is required
- sessionFs.sessionStatePath is required
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/5b3bdcfd8f69807f.
Report an issue: GitHub.
Appendix: source
Thrown at python/copilot/client.py:420
"""
callbacks: dict[str, BearerTokenProvider] = {}
if provider is not None:
singular = provider.get("bearer_token_provider")
if singular is not None:
callbacks[_DEFAULT_BEARER_TOKEN_PROVIDER_NAME] = singular
if providers:
for named in providers:
callback = named.get("bearer_token_provider")
if callback is not None:
callbacks[named["name"]] = callback
return callbacks
def _validate_session_fs_config(config: SessionFsConfig) -> None:
if not config.get("initial_working_directory"):
raise ValueError("session_fs.initial_working_directory is required")
if not config.get("session_state_path"):
raise ValueError("session_fs.session_state_path is required")
if config.get("conventions") not in ("posix", "windows"):
raise ValueError("session_fs.conventions must be either 'posix' or 'windows'")
def _mcp_servers_to_wire(
servers: dict[str, Any],
) -> dict[str, Any]:
"""Convert MCP server configs from public API format to wire format.
Renames ``working_directory`` key to ``cwd`` in each server config dict.
"""
wire: dict[str, Any] = {}
for name, config in servers.items():
if "working_directory" in config:
config = {**config, "cwd": config["working_directory"]}
del config["working_directory"]
wire[name] = config
return wireView on GitHub (pinned to cd8cf15dc3)