langchain-ai/deepagents · error · ValueError
`is_expired` is only meaningful when `logged_in` is True.
Error message
`is_expired` is only meaningful when `logged_in` is True.
What it means
`__post_init__` invariant: `is_expired` is a derived property meaningful only when `logged_in` is True; a state with `logged_in=False` and a truthy `is_expired` is contradictory and raises ValueError.
Source
Thrown at libs/code/deepagents_code/integrations/openai_codex.py:115
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.
Stored under Deep Agents' own state dir
(`~/.deepagents/.state/chatgpt-auth.json`) so the credential lives
alongside the rest of the app's state rather than in `langchain_openai`'s
default `~/.langchain`.
"""
from deepagents_code.model_config import DEFAULT_STATE_DIR
return DEFAULT_STATE_DIR / "chatgpt-auth.json"View on GitHub (pinned to a1af029e6e)
Solutions
- Set `expires_at=None` (and thus a falsy `is_expired`) when `logged_in=False`.
- Keep `logged_in=True` if expiry tracking is needed.
- Ensure any state-transformation code resets expiry-derived fields on logout.
Example fix
// before state = CodexAuthState(logged_in=False, expires_at=past_timestamp) // after state = CodexAuthState(logged_in=False, expires_at=None)
Defensive patterns
Strategy: validation
Validate before calling
def valid_state(state) -> bool:
if state.logged_in:
return state.expires_at is not None
return state.expires_at is None and not state.is_expired and not (state.account_id or state.plan_type) Try / catch
try:
state = CodexAuthState(**fields)
except ValueError as exc:
logger.warning('contradictory token state: %s', exc)
state = CodexAuthState(logged_in=False) Prevention
- Treat is_expired/expiry fields as meaningful only for logged-in states
- Reset expiry-derived fields whenever logged_in flips to False
- Add an invariant round-trip test when persisting/restoring state
When it happens
Trigger: Constructing with `logged_in=False` while the derived `is_expired` evaluates truthy (typically because `expires_at` leaked into the object or `is_expired` was set directly), e.g. `TokenState(logged_in=False, expires_at=past_time)` per its internal logic.
Common situations: Logged-out snapshots that retain an expired timestamp, test fixtures built with all fields populated, or custom subclasses overriding the expiry logic.
Related errors
- `expires_at` is only meaningful when `logged_in` is True.
- `unreadable_reason` implies the token is not usable; `logged
- `expires_at` must be set when `logged_in` is True.
- PendingNotification.key must be non-empty
- PendingNotification {self.key!r} must declare at least one a
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/db1304ad246f9586.
Report an issue: GitHub.