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

  1. Start the daily series at the first day with at least 1 star
  2. Drop leading zero-star points from daily before writing state
  3. 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

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


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