Skip to content

Python list_sessions docstring example uses a nonexistent sessionId attribute #2098

Description

@examon

Summary

The Example: block in the docstring of CopilotClient.list_sessions (Python SDK) prints
session.sessionId, an attribute that does not exist on the objects the method returns.
Copying the documented example raises AttributeError.

list_sessions is annotated -> list[SessionMetadata] and builds its results with
SessionMetadata.from_dict(...). SessionMetadata is a dataclass that declares session_id;
sessionId exists only as the wire/JSON key, mapped to session_id inside
SessionMetadata.from_dict / to_dict. There is no sessionId property, alias, or
__getattr__ fallback, so the documented access can never succeed.

Where

python/copilot/client.py, in the CopilotClient.list_sessions docstring:

Example:
    >>> sessions = await client.list_sessions()
    >>> for session in sessions:
    ...     print(f"Session: {session.sessionId}")   # <- no such attribute

The returned type:

@dataclass
class SessionMetadata:
    """Metadata about a session"""

    session_id: str  # Session identifier
    start_time: datetime
    modified_time: datetime
    is_remote: bool
    summary: str | None = None
    context: SessionContext | None = None

Reproduction

No server, model, or credentials needed. The snippet constructs a SessionMetadata exactly the
way list_sessions does internally, then performs the documented access.

pip install github-copilot-sdk
from copilot.client import SessionMetadata

# The wire payload shape `list_sessions` feeds into SessionMetadata.from_dict(...)
wire = {
    "sessionId": "abc-123",
    "startTime": "2026-06-27T10:00:00Z",
    "modifiedTime": "2026-06-27T10:05:00Z",
    "isRemote": False,
    "summary": "demo session",
}

session = SessionMetadata.from_dict(wire)

# The attribute that actually exists:
print(f"[ok] session.session_id = {session.session_id}")

# The attribute the documented example tells you to read:
print(f"Session: {session.sessionId}")

Expected

The documented example prints each session's id, e.g. Session: abc-123.

Actual

[ok] session.session_id = abc-123
Traceback (most recent call last):
  File "repro.py", line 18, in <module>
    print(f"Session: {session.sessionId}")
                      ^^^^^^^^^^^^^^^^^
AttributeError: 'SessionMetadata' object has no attribute 'sessionId'. Did you mean: 'session_id'?

Notes

session_id is the correct spelling for this type, and it is what the rest of the SDK already
uses and asserts:

  • the shipped dataclass field itself;
  • the end-to-end tests, which assert session_id on exactly this return value
    (python/e2e/test_session_e2e.py);
  • the generated sibling type SessionMetadataSnapshot, which also uses session_id;
  • the sibling docstring for get_session_metadata, which documents the same object correctly as
    metadata.start_time.

Other bindings document this method with their own idiomatic spelling of the same wire field, so
the Python docstring is the only one affected: Go uses session.SessionID (go/client.go) and
.NET uses session.SessionId (dotnet/src/Client.cs).

Nothing in the repository executes these docstring examples (there is no --doctest-modules
setting and the docs-validation job only extracts Markdown under docs/), which is why lint,
type-checking, and the test suite all pass with the defect present.

The fix is to correct the documented attribute name. It is a docstring-only change with no
public API, behavior, or wire format impact.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions