HKUDS/Vibe-Trading · error · ValueError

timezone {tz!r} is not a recognized IANA timezone key

Error message

timezone {tz!r} is not a recognized IANA timezone key

What it means

Raised by validate_timezone in agent/src/scheduled_research/models.py:176 when a non-None timezone string cannot be constructed into a ZoneInfo, i.e. it is not a recognized IANA timezone database key. The library validates timezones eagerly so scheduled jobs always have a computable local time. It wraps the underlying ZoneInfoNotFoundError/ValueError as ValueError with the offending value shown.

Source

Thrown at agent/src/scheduled_research/models.py:176

    """Raise ``ValueError`` when *tz* is not a resolvable IANA timezone key.

    ``None`` is always valid and means legacy UTC semantics. Resolution goes
    through :class:`zoneinfo.ZoneInfo`, so whatever validates here is exactly
    what the executor can evaluate later.

    Args:
        tz: An IANA timezone key such as ``"Pacific/Auckland"``, or ``None``.

    Raises:
        ValueError: When *tz* is not ``None`` and cannot be resolved.
    """
    validate_timezone_shape(tz)
    if tz is None:
        return
    try:
        ZoneInfo(tz)
    except Exception as exc:
        raise ValueError(f"timezone {tz!r} is not a recognized IANA timezone key") from exc


# ---------------------------------------------------------------------------
# Status enum
# ---------------------------------------------------------------------------


class JobStatus(str, Enum):
    """Lifecycle status of a scheduled research job."""

    PENDING = "pending"
    RUNNING = "running"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"
    EXPIRED = "expired"

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Use the exact IANA key, e.g. 'America/New_York', 'Europe/Berlin', 'UTC'
  2. Strip/normalize user input before passing: tz = tz.strip() if tz else None
  3. Validate eagerly in your own layer with zoneinfo.available_timezones() or a try/except ZoneInfo(tz) probe
  4. On Windows, pip install tzdata if even valid keys fail
  5. Pass None to accept the default timezone instead of guessing a string

Example fix

// before
job = create_scheduled_run(..., tz=user_tz)  # user_tz = 'PST'

// after
from zoneinfo import ZoneInfo

def safe_tz(raw):
    if raw is None:
        return None
    try:
        ZoneInfo(raw)
        return raw
    except Exception:
        return None  # fall back to default

job = create_scheduled_run(..., tz=safe_tz(user_tz))
Defensive patterns

Strategy: validation

Validate before calling

from zoneinfo import ZoneInfo

def is_valid_tz(tz):
    if tz is None:
        return True
    try:
        ZoneInfo(tz)
        return True
    except Exception:
        return False

assert is_valid_tz("America/New_York")
assert not is_valid_tz("PST")

Type guard

from typing import Optional
from zoneinfo import ZoneInfo

def valid_timezone(tz: object) -> Optional[str]:
    """Return tz if it is None or a valid IANA key, else None."""
    if tz is None:
        return None
    if isinstance(tz, str):
        try:
            ZoneInfo(tz)
            return tz
        except Exception:
            return None
    return None

Try / catch

from agent.src.scheduled_research.models import create_scheduled_run

try:
    run = create_scheduled_run(..., tz=tz)
except ValueError as exc:
    if "not a recognized IANA timezone" in str(exc):
        run = create_scheduled_run(..., tz=None)  # fall back to default
    else:
        raise

Prevention

When it happens

Trigger: Calling create_scheduled_run, next_due, to_job, or build_job_from_draft with tz set to something like 'PST', 'UTC+2', 'America/New_York ' (whitespace), or a typo like 'Europa/Berlin'. Note tz=None is allowed and returns early; only non-None invalid strings raise.

Common situations: Using POSIX tz strings ('US/Eastern', 'GMT+1') instead of IANA keys; carrying over timezone names from a UI dropdown or legacy config; deprecated/renamed zone keys across tzdata versions; missing tzdata package on Windows making all lookups fail.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/27a885a06e3cb3e3. Report an issue: GitHub.