666ghj/MiroFish · error · StarHistoryError
first reconstruction point must have stars
Error message
first reconstruction point must have stars
What it means
Raised by validate_state() when the first entry of reconstruction.daily has stars <= 0. The first reconstructed point represents the day the first star was given, so it must be strictly positive; a zero-star first point makes the monotonic star sequence meaningless.
Source
Thrown at scripts/star_history.py:413
previous_day: date | None = None
previous_stars = 0
for index, raw_point in enumerate(daily):
if not isinstance(raw_point, dict):
raise StarHistoryError("reconstruction point must be an object")
_expect_keys(raw_point, {"date", "stars"}, "reconstruction point")
raw_date = raw_point["date"]
if not isinstance(raw_date, str):
raise StarHistoryError("reconstruction date must be a string")
try:
point_day = date.fromisoformat(raw_date)
except ValueError as exc:
raise StarHistoryError("reconstruction date is invalid") from exc
if point_day.isoformat() != raw_date:
raise StarHistoryError("reconstruction date is not canonical")
stars = _strict_non_negative_int(raw_point["stars"], "reconstruction stars")
if index == 0 and stars <= 0:
raise StarHistoryError("first reconstruction point must have stars")
if previous_day is not None and point_day <= previous_day:
raise StarHistoryError("reconstruction dates must be strictly increasing")
if index > 0 and stars <= previous_stars:
raise StarHistoryError("reconstruction stars must be strictly increasing")
if point_day >= generated_at.date():
raise StarHistoryError("reconstruction must contain only completed UTC dates")
previous_day = point_day
previous_stars = stars
snapshots = state["snapshots"]
if not isinstance(snapshots, list):
raise StarHistoryError("snapshots must be a list")
previous_snapshot: datetime | None = None
first_snapshot: datetime | None = None
for raw_snapshot in snapshots:
if not isinstance(raw_snapshot, dict):
raise StarHistoryError("snapshot must be an object")
_expect_keys(raw_snapshot, {"at", "stars"}, "snapshot")View on GitHub (pinned to b5b53acc57)
Solutions
- Start the daily series at the first day with at least 1 star
- Drop leading zero-star points from daily before writing state
- Check the bucketing logic that aggregates starred_at timestamps into days
Example fix
// before
"daily": [{"date": "2024-01-01", "stars": 0}, {"date": "2024-01-02", "stars": 5}]
// after
"daily": [{"date": "2024-01-02", "stars": 5}] Defensive patterns
Strategy: validation
Validate before calling
daily = [p for p in daily if not (p is daily[0] and p["stars"] == 0)] daily = daily[next((i for i, p in enumerate(daily) if p["stars"] > 0), len(daily)):]
Type guard
def first_point_has_stars(daily: list) -> bool:
return not daily or daily[0]["stars"] > 0 Try / catch
try:
validate_state(state)
except StarHistoryError as exc:
if "first reconstruction point must have stars" in str(exc):
# strip leading zero-star days, then re-validate
... Prevention
- Start the series at the first starred day, not repo creation day
- Skip zero-count buckets when aggregating starred_at timestamps
- Test generated state with validate_state before writing
When it happens
Trigger: validate_state(state) where daily[0]['stars'] is 0 (negative values are already rejected by _strict_non_negative_int).
Common situations: Padding the daily series with a zero point at the repo-creation date; off-by-one bucketing that assigns the first star to day zero; resetting state and reusing a template.
Related errors
- reconstruction stars must be strictly increasing
- {label} must use YYYY-MM-DDTHH:MM:SSZ
- {label} is not a valid UTC timestamp
- {label} contains missing or unknown fields
- history state must be a JSON object
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/6a00ed9e91ffc9a0.
Report an issue: GitHub.