github/copilot-sdk · error · ValueError

unknown session

Error message

unknown session {params.session_id}

What it means

The hook dispatcher's invoke looks up the session by params.session_id via the provided getter; if no session matches, it raises ValueError('unknown session ...'). Hooks are routed to a specific session, so an unknown ID means the hook request cannot be delivered and processing stops.

Solutions

  1. Confirm the session_id exists (client.get_session / session map) before sending or processing hooks
  2. Recreate the session if it was stopped, and re-send the request with the new session_id
  3. Guard against closing sessions while hooks are pending; check session lifecycle ordering in your code
  4. Log the valid session IDs at failure time to spot stale IDs

Example fix

// before
session = client.get_session(session_id)
session.stop()  # session removed while hooks may still arrive
// after
session = client.get_session(session_id)
# drain/ignore pending hooks first, then stop
if not has_pending_hooks(session_id):
    session.stop()
Defensive patterns

Strategy: try-catch

Validate before calling

if client.get_session(params.session_id) is None:
    raise LookupError(f"session {params.session_id} not found; skip hook")

Try / catch

try:
    output = await hook_handler.invoke(params)
except ValueError as e:
    if str(e).startswith("unknown session"):
        logger.warning("dropping hook for stale session %s", params.session_id)
    else:
        raise

Prevention

When it happens

Trigger: A hook invoke request arrives with a session_id that was never created, or the session was already closed/removed from the client's session map before the hook fired.

Common situations: Client restart or session timeout between agent event and hook delivery; reusing a session ID string from a previous run; concurrent code closing a session while hooks are still in flight; copying a session_id with extra characters.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at python/copilot/client.py:795

        # so the public tagged dictionary is already in the expected wire shape.
        return cast(GitHubTokenAcquireResult, result)


class _HooksAdapter:
    """Adapts session-scoped hook dispatch to the generated ``HooksHandler`` protocol.

    ``hooks.invoke`` is a client-global RPC method whose payload carries a
    ``sessionId``. This adapter routes each invocation to the matching session's
    registered hook handlers.
    """

    def __init__(self, get_session: Callable[[str], CopilotSession | None]) -> None:
        self._get_session = get_session

    async def invoke(self, params: _HookInvokeRequest) -> _HookInvokeResponse:
        session = self._get_session(params.session_id)
        if session is None:
            raise ValueError(f"unknown session {params.session_id}")
        output = await session._handle_hooks_invoke(params.hook_type.value, params.input)
        return _HookInvokeResponse(output=output)


@dataclass
class _CopilotClientOptions:
    """Internal configuration carrier used by :class:`CopilotClient`.

    This is not part of the public API: ``CopilotClient`` accepts all of
    these options as keyword arguments directly.
    """

    connection: RuntimeConnection | None = None
    working_directory: str | None = None
    log_level: LogLevel = "info"
    env: dict[str, str] | None = None
    github_token: str | None = None
    base_directory: str | None = None

View on GitHub (pinned to cd8cf15dc3)