langchain-ai/deepagents · error · ValueError
`unreadable_reason` implies the token is not usable; `logged
Error message
`unreadable_reason` implies the token is not usable; `logged_in` must be False.
What it means
This ValueError is raised by a dataclass `__post_init__` invariant check on a Codex auth token state object. The library enforces that `unreadable_reason` (indicating the stored token could not be read/decoded) can only coexist with `logged_in=False`, since an unreadable token means the user cannot be considered logged in. It protects callers from a contradictory state object.
Source
Thrown at libs/code/deepagents_code/integrations/openai_codex.py:106
The valid/expired/missing/unreadable states are encoded as a
`bool` plus optionals rather than a tagged union, so this guards the
cross-field rules the attribute docs promise — catching future
construction drift the same way upstream's `_ChatGPTToken` guards
its own invariants.
Raises:
ValueError: An unreadable token is also marked `logged_in`; a
logged-out snapshot carries an `expires_at`, `is_expired`,
`account_id`, or `plan_type`; or a logged-in snapshot is
missing its `expires_at`.
"""
if self.unreadable_reason is not None and self.logged_in:
msg = (
"`unreadable_reason` implies the token is not usable; "
"`logged_in` must be False."
)
raise ValueError(msg)
if self.logged_in and self.expires_at is None:
msg = "`expires_at` must be set when `logged_in` is True."
raise ValueError(msg)
if not self.logged_in and self.expires_at is not None:
msg = "`expires_at` is only meaningful when `logged_in` is True."
raise ValueError(msg)
if not self.logged_in and self.is_expired:
msg = "`is_expired` is only meaningful when `logged_in` is True."
raise ValueError(msg)
if not self.logged_in and (self.account_id or self.plan_type):
msg = (
"`account_id`/`plan_type` are only meaningful when `logged_in` is True."
)
raise ValueError(msg)
def default_store_path() -> Path:
"""Return the ChatGPT OAuth token store path.View on GitHub (pinned to a1af029e6e)
Solutions
- Set `logged_in=False` whenever `unreadable_reason` is populated.
- If the user actually authenticated, clear `unreadable_reason` (set to None) and supply `expires_at` instead.
- Re-read the auth file and recover the token so neither invariant is violated.
Example fix
// before state = CodexAuthState(unreadable_reason='token file corrupt', logged_in=True) // after state = CodexAuthState(unreadable_reason='token file corrupt', logged_in=False)
Defensive patterns
Strategy: validation
Validate before calling
def validate_auth_state(state) -> bool:
return not (state.unreadable_reason is not None and state.logged_in) Try / catch
try:
state = CodexAuthState(unreadable_reason=reason, logged_in=True)
except ValueError as exc:
logger.warning('invalid auth state: %s', exc)
state = CodexAuthState(unreadable_reason=reason, logged_in=False) Prevention
- Always set logged_in=False when unreadable_reason is populated
- Construct auth state through a single factory that enforces invariants
- Add a unit test for each invariant branch
When it happens
Trigger: Constructing the dataclass with both `unreadable_reason` set to a non-None value AND `logged_in=True`, e.g. `TokenState(unreadable_reason='corrupt file', logged_in=True)`.
Common situations: Hand-building a token state from partially recovered auth files, deserializing a snapshot where a login was attempted but token parsing failed, or code that sets `unreadable_reason` after marking the session logged in.
Related errors
- ColdCacheWarning age_seconds={self.age_seconds!r} does not p
- `expires_at` must be set when `logged_in` is True.
- `expires_at` is only meaningful when `logged_in` is True.
- `is_expired` is only meaningful when `logged_in` is True.
- PendingNotification.key must be non-empty
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/8c4f8421c97e3bd6.
Report an issue: GitHub.