HKUDS/DeepTutor · error · ValueError

unknown timezone {schedule.tz!r}

Error message

unknown timezone {schedule.tz!r}

What it means

validate_schedule catches any exception from zoneinfo.ZoneInfo(schedule.tz) on cron schedules and re-raises ValueError('unknown timezone ...'). The tz string must be an IANA zone name resolvable via system tzdata; anything else fails.

Source

Thrown at deeptutor/services/cron/service.py:170

    """Reject schedules that could never run (raises ValueError)."""
    if schedule.kind == "at":
        if not schedule.at_ms:
            raise ValueError("'at' schedules need a time")
        if schedule.at_ms <= _now_ms():
            raise ValueError("'at' time is in the past")
        return
    if schedule.kind == "every":
        if not schedule.every_seconds or schedule.every_seconds < 30:
            raise ValueError("'every' interval must be at least 30 seconds")
        return
    if schedule.kind == "cron":
        if schedule.tz:
            try:
                from zoneinfo import ZoneInfo

                ZoneInfo(schedule.tz)
            except Exception:
                raise ValueError(f"unknown timezone {schedule.tz!r}") from None
        # Raises ValueError on bad/unsupported expressions.
        if compute_next_run(schedule, _now_ms()) is None:
            raise ValueError(f"cron expression {schedule.expr!r} never fires")
        return
    raise ValueError(f"unknown schedule kind {schedule.kind!r}")


class CronService:
    """Single-process job store + scheduler."""

    def __init__(
        self,
        store_path: Path,
        on_job: Callable[[CronJob], Awaitable[tuple[str, str | None]]] | None = None,
    ) -> None:
        """``on_job`` returns ``(status, error)`` with status ok/error/skipped."""
        self.store_path = store_path
        self.on_job = on_job

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Use an exact IANA name like 'Europe/Berlin' or 'America/New_York'
  2. Install tzdata: apt-get install -y tzdata (or apk add tzdata; pip install tzdata on Windows/slim)
  3. Verify with ZoneInfo(name) in a shell before deploying the schedule

Example fix

# before
sched = CronSchedule(kind="cron", expr="0 9 * * *", tz="CET")
# after
sched = CronSchedule(kind="cron", expr="0 9 * * *", tz="Europe/Paris")
# slim Docker: RUN apt-get update && apt-get install -y tzdata
Defensive patterns

Strategy: validation

Validate before calling

from zoneinfo import ZoneInfo

def valid_tz(name: str | None) -> bool:
    if not name:
        return True
    try:
        ZoneInfo(name)
        return True
    except Exception:
        return False

assert valid_tz(schedule.tz), f"bad tz {schedule.tz!r}"

Try / catch

try:
    svc.add_job(schedule, ...)
except ValueError as e:
    if "unknown timezone" in str(e):
        schedule.tz = "UTC"
        svc.add_job(schedule, ...)
    else:
        raise

Prevention

When it happens

Trigger: CronSchedule(kind="cron", expr="0 9 * * *", tz="America/New_Yorkk") or non-IANA strings like 'EST'/'UTC+2'; also containers missing /usr/share/zoneinfo or the tzdata package.

Common situations: Typo'd IANA names; offset-style strings instead of region/city; minimal Docker images (alpine/slim) without tzdata; Windows lacking the tzdata pip package.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/6cac814f32cbf39f. Report an issue: GitHub.