langchain-ai/deepagents · error · ValueError

ColdCacheWarning age_seconds={self.age_seconds!r} does not p

Error message

ColdCacheWarning age_seconds={self.age_seconds!r} does not pair with reason={self.reason!r}: an age is required except for 'age_unknown', which must have none

What it means

ColdCacheWarning pairs a reason with an optional age_seconds; __post_init__ enforces the XOR invariant that age_seconds is present exactly when reason != 'age_unknown' (and absent for 'age_unknown'). This keeps rendering honest: a warning never claims an age it cannot know, and never hides a known age.

Source

Thrown at libs/code/deepagents_code/cold_cache.py:260

    """

    reason: ColdCacheReason
    """Why the cache is treated as cold; selects the modal's copy."""

    def __post_init__(self) -> None:
        """Enforce the documented `age_seconds`/`reason` pairing.

        Raises:
            ValueError: When an age is present for `age_unknown`, or absent for
                any other reason.
        """
        if (self.age_seconds is None) != (self.reason == "age_unknown"):
            msg = (
                f"ColdCacheWarning age_seconds={self.age_seconds!r} does not "
                f"pair with reason={self.reason!r}: an age is required except "
                f"for 'age_unknown', which must have none"
            )
            raise ValueError(msg)


def debug_stand_in_policy() -> PromptCachePolicy:
    """Build the placeholder policy used by `DEEPAGENTS_CODE_DEBUG_COLD_CACHE`.

    Keeps the modal reachable on providers with no documented cache policy.
    Lives here rather than in the caller so the Anthropic window and minimum
    stay tied to `_ANTHROPIC_MIDDLEWARE_TTL_SECONDS` and
    `_ANTHROPIC_DEFAULT_MINIMUM_TOKENS` instead of being re-hardcoded, which
    would silently drift the moment either constant is revised.

    The provider name is deliberately Anthropic's: under the debug flag the
    modal may therefore cite Anthropic retention while a different provider is
    active. The figures are illustrative in that mode, not real estimates.

    Returns:
        Stand-in policy shaped like Anthropic's.
    """

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Use reason='age_unknown' when the cache age is genuinely unknown and pass age_seconds=None.
  2. Provide the measured age_seconds for any concrete reason (e.g. 'stale_cache') instead of None.
  3. Derive the reason from the presence of the age ((age_seconds is None) -> 'age_unknown') instead of hardcoding them independently.

Example fix

// before
warn = ColdCacheWarning(reason="stale_cache", age_seconds=None)
// after
warn = ColdCacheWarning(reason="stale_cache", age_seconds=measured_age) if measured_age is not None else ColdCacheWarning(reason="age_unknown", age_seconds=None)
Defensive patterns

Strategy: type-guard

Validate before calling

reason = "age_unknown" if age is None else concrete_reason
warn = ColdCacheWarning(reason=reason, age_seconds=age)

Type guard

def is_valid_warning_args(reason: str, age: float | None) -> bool:
    return (age is None) == (reason == "age_unknown")

Try / catch

try:
    warn = ColdCacheWarning(reason=reason, age_seconds=age)
except ValueError as e:
    logger.warning("dropping malformed cold-cache warning: %s", e)
    warn = None

Prevention

When it happens

Trigger: Constructing ColdCacheWarning(reason='age_unknown', age_seconds=120) or ColdCacheWarning(reason='stale_cache', age_seconds=None) — either mismatch of the pairing raises.

Common situations: Plumbing an age through code paths where it is unknown but leaving the reason as a concrete one, or defaulting age_seconds=None for a reason that does have a measured age.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/381d4dc7b6dbc9b6. Report an issue: GitHub.