666ghj/MiroFish · error · StarHistoryError

history timezone must be UTC

Error message

history timezone must be UTC

What it means

validate_state requires state['timezone'] to be exactly the string 'UTC'; anything else raises StarHistoryError('history timezone must be UTC'). All stored timestamps use the strict Z-suffix UTC format and all bucket math assumes UTC, so a state declaring another zone would be internally inconsistent.

Source

Thrown at scripts/star_history.py:364

        raise StarHistoryError("history state must be a JSON object")
    _expect_keys(
        state,
        {
            "schema_version",
            "repository",
            "timezone",
            "ongoing_interval_days",
            "reconstruction",
            "snapshots",
        },
        "history state",
    )
    if state["schema_version"] != 1 or type(state["schema_version"]) is not int:
        raise StarHistoryError("unsupported history schema_version")
    if state["repository"] != REPOSITORY:
        raise StarHistoryError("history repository does not match configured repository")
    if state["timezone"] != "UTC":
        raise StarHistoryError("history timezone must be UTC")
    if (
        state["ongoing_interval_days"] != INTERVAL_DAYS
        or type(state["ongoing_interval_days"]) is not int
    ):
        raise StarHistoryError(
            f"history interval must be exactly {INTERVAL_DAYS} days"
        )

    reconstruction = state["reconstruction"]
    if not isinstance(reconstruction, dict):
        raise StarHistoryError("reconstruction must be an object")
    _expect_keys(
        reconstruction,
        {"method", "generated_at", "daily"},
        "reconstruction",
    )
    reconstruction_method = reconstruction["method"]
    if reconstruction_method not in {

View on GitHub (pinned to b5b53acc57)

Solutions

  1. Set the field back to exactly 'UTC' and ensure all timestamps in the file are Z-suffixed UTC
  2. Or regenerate the state file from scratch
  3. Keep all timezone conversion at the presentation layer, not in the state file

Example fix

// before (state file)
"timezone": "America/New_York"

// after (state file)
"timezone": "UTC"
Defensive patterns

Strategy: validation

Validate before calling

if state.get("timezone") != "UTC":
    raise StarHistoryError(f"state timezone {state.get('timezone')!r} unsupported; must be 'UTC'")

Type guard

def state_timezone_is_utc(state: object) -> TypeGuard[dict]:
    return isinstance(state, dict) and state.get("timezone") == "UTC"

Try / catch

try:
    validate_state(state)
except StarHistoryError as exc:
    if "timezone must be UTC" in str(exc):
        regenerate_state_file()
    else:
        raise

Prevention

When it happens

Trigger: State file with timezone: 'utc', 'GMT', 'Etc/UTC', '+00:00', or an actual local zone like 'America/New_York' — usually from hand-editing or a third-party writer.

Common situations: Someone 'localized' the state file by editing the timezone field; a fork added timezone support but ran against the strict validator.

Related errors


AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14). Data as JSON: /api/errors/df5a1244abf3d1f8. Report an issue: GitHub.