666ghj/MiroFish · error · StarHistoryError
{label} is not a valid UTC timestamp
Error message
{label} is not a valid UTC timestamp What it means
A state timestamp passed the strict regex (digits in the right slots) but datetime.strptime still raised ValueError — i.e. the value is structurally right yet semantically invalid, like '2024-02-30T00:00:00Z' or '2024-01-15T25:61:00Z'. _parse_state_timestamp chains it into StarHistoryError(f'{label} is not a valid UTC timestamp').
Source
Thrown at scripts/star_history.py:323
def _parse_github_timestamp(value: str) -> datetime:
try:
parsed = datetime.fromisoformat(value.replace("Z", "+00:00"))
except ValueError as exc:
raise StarHistoryError("GitHub returned an invalid star timestamp") from exc
if parsed.tzinfo is None or parsed.utcoffset() != timedelta(0):
raise StarHistoryError("GitHub star timestamp was not UTC")
return parsed.astimezone(UTC)
def _parse_state_timestamp(value: Any, label: str) -> datetime:
if not isinstance(value, str) or not STATE_TIMESTAMP_RE.fullmatch(value):
raise StarHistoryError(f"{label} must use YYYY-MM-DDTHH:MM:SSZ")
try:
parsed = datetime.strptime(value, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=UTC)
except ValueError as exc:
raise StarHistoryError(f"{label} is not a valid UTC timestamp") from exc
return parsed
def _format_state_timestamp(value: datetime) -> str:
normalized = _normalize_now(value)
return normalized.strftime("%Y-%m-%dT%H:%M:%SZ")
def _normalize_now(value: datetime) -> datetime:
if value.tzinfo is None or value.utcoffset() != timedelta(0):
raise StarHistoryError("clock must return a UTC datetime")
return value.astimezone(UTC).replace(microsecond=0)
def _expect_keys(value: Mapping[str, Any], expected: set[str], label: str) -> None:
actual = set(value)
if actual != expected:
raise StarHistoryError(f"{label} contains missing or unknown fields")View on GitHub (pinned to b5b53acc57)
Solutions
- Regenerate the state file instead of hand-editing it
- Fix the specific impossible timestamp (check Feb 29 in non-leap years)
- Make any external generator use datetime.strftime('%Y-%m-%dT%H:%M:%SZ') so ranges are always valid
Example fix
// before (state file) "generated_at": "2024-02-30T10:30:00Z" // after (state file) "generated_at": "2024-02-29T10:30:00Z"
Defensive patterns
Strategy: validation
Validate before calling
from datetime import datetime
def state_timestamp_semantically_valid(value: str) -> bool:
try:
datetime.strptime(value, "%Y-%m-%dT%H:%M:%SZ")
return True
except ValueError:
return False
# run after the regex check — catches 2024-02-30, hour 25, etc. Type guard
def is_valid_state_timestamp(value: object) -> TypeGuard[str]:
return (
isinstance(value, str)
and bool(STATE_TIMESTAMP_RE.fullmatch(value))
and state_timestamp_semantically_valid(value)
) Try / catch
try:
validate_state(state)
except StarHistoryError as exc:
if "not a valid UTC timestamp" in str(exc):
# regex-passed but impossible date (e.g. Feb 30) — file is corrupt; rebuild
regenerate_state_file()
else:
raise Prevention
- Produce timestamps only via datetime.strftime, never by string concatenation of numbers
- Watch leap-year edges (Feb 29) in hand-made test data
When it happens
Trigger: Hand-edited state file with an impossible date (Feb 30, April 31) or out-of-range hour/minute/second; a generator that zero-pads arbitrary integers without range checks.
Common situations: Manual edits to the state JSON; a buggy external tool that fabricates timestamps by string formatting instead of using datetime.strftime.
Related errors
- {label} must use YYYY-MM-DDTHH:MM:SSZ
- GitHub returned an invalid star timestamp
- GitHub star timestamp was not UTC
- clock must return a UTC datetime
- {label} contains missing or unknown fields
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/cee15bb45c0e56b3.
Report an issue: GitHub.