github/copilot-sdk · error · ValueError
invalid exit plan mode request payload
Error message
invalid exit plan mode request payload
What it means
ValueError raised when handling an exitPlanMode request whose payload fails validation: sessionId must be non-empty, summary must be a string, actions must be a list, and recommendedAction must be a string. The check fires twice for the two groups of fields.
Solutions
- Match CLI and SDK versions so plan-mode payloads conform to the expected schema
- Dump the incoming params with debug logging to identify the offending field
- Update custom middleware that transforms or rebuilds request params
- Wrap callback handling to log and skip malformed plan-mode requests instead of crashing
Defensive patterns
Strategy: validation
Validate before calling
def is_valid_exit_plan_params(params: dict) -> bool:
return (bool(params.get("sessionId"))
and isinstance(params.get("summary"), str)
and isinstance(params.get("actions"), list)
and isinstance(params.get("recommendedAction"), str)) Type guard
def valid_exit_plan(params) -> bool:
return (isinstance(params, dict)
and bool(params.get("sessionId"))
and isinstance(params.get("summary"), str)
and isinstance(params.get("actions"), list)
and isinstance(params.get("recommendedAction"), str)) Try / catch
try:
await client._handle_exit_plan_mode_request(params)
except ValueError as e:
if "invalid exit plan mode request payload" in str(e):
log.error("malformed exitPlanMode.request: %r", params)
else:
raise Prevention
- Upgrade CLI and SDK together when plan-mode schema changes
- Validate exitPlanMode payloads in test harnesses/proxies before forwarding
- Log offending payloads to catch protocol drift early
- Add schema tests for plan-mode callback fields
When it happens
Trigger: CLI server sends an exitPlanMode.request callback with missing/empty sessionId, a non-string summary, a non-list actions field, or a non-string recommendedAction.
Common situations: CLI/SDK version drift changing the plan-mode payload schema; custom proxies or test harnesses emitting malformed callbacks; fields renamed in a newer protocol version.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Invalid exit plan mode request payload
- invalid user input request payload
- invalid auto mode switch request payload
- invalid systemMessage.transform payload
- Invalid user input request payload
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/ea2aba554f172ff6.
Report an issue: GitHub.
Appendix: source
Thrown at python/copilot/client.py:4963
raise ValueError("invalid user input request payload")
with self._sessions_lock:
session = self._sessions.get(session_id)
if not session:
raise ValueError(f"unknown session {session_id}")
result = await session._handle_user_input_request(params)
return {"answer": result["answer"], "wasFreeform": result["wasFreeform"]}
async def _handle_exit_plan_mode_request(self, params: dict) -> dict:
"""Handle an exitPlanMode.request callback from the CLI server."""
session_id = params.get("sessionId")
summary = params.get("summary")
actions = params.get("actions")
recommended_action = params.get("recommendedAction")
if not session_id or not isinstance(summary, str):
raise ValueError("invalid exit plan mode request payload")
if not isinstance(actions, list) or not isinstance(recommended_action, str):
raise ValueError("invalid exit plan mode request payload")
with self._sessions_lock:
session = self._sessions.get(session_id)
if not session:
raise ValueError(f"unknown session {session_id}")
return dict(await session._handle_exit_plan_mode_request(params))
async def _handle_auto_mode_switch_request(self, params: dict) -> dict:
"""Handle an autoModeSwitch.request callback from the CLI server."""
session_id = params.get("sessionId")
if not session_id:
raise ValueError("invalid auto mode switch request payload")
with self._sessions_lock:
session = self._sessions.get(session_id)View on GitHub (pinned to cd8cf15dc3)