666ghj/MiroFish · error · StarHistoryError

reconstruction stars must be strictly increasing

Error message

reconstruction stars must be strictly increasing

What it means

Raised by validate_state() when a daily point after the first has stars <= the previous point's stars. Daily star counts are cumulative totals, so they must strictly increase over time; equal or decreasing values indicate corrupted aggregation or unsorted data.

Source

Thrown at scripts/star_history.py:417

        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")
        snapshot_at = _parse_state_timestamp(raw_snapshot["at"], "snapshot.at")
        _strict_non_negative_int(raw_snapshot["stars"], "snapshot stars")
        if previous_snapshot is not None and snapshot_at <= previous_snapshot:
            raise StarHistoryError("snapshot timestamps must be strictly increasing")

View on GitHub (pinned to b5b53acc57)

Solutions

  1. Ensure each daily point stores the cumulative total star count at end of that UTC day, strictly greater than the prior day
  2. Re-run the reconstruction step to rebuild daily from starred_at data
  3. If deltas were written, convert them to running totals before validation

Example fix

// before
"daily": [{"date": "2024-01-01", "stars": 100}, {"date": "2024-01-02", "stars": 5}]
// after
"daily": [{"date": "2024-01-01", "stars": 100}, {"date": "2024-01-02", "stars": 105}]
Defensive patterns

Strategy: validation

Validate before calling

for i in range(1, len(daily)):
    if daily[i]["stars"] <= daily[i - 1]["stars"]:
        raise ValueError(f"non-increasing stars at {daily[i]['date']}")

Type guard

def stars_strictly_increasing(daily: list) -> bool:
    return all(
        daily[i]["stars"] > daily[i - 1]["stars"] for i in range(1, len(daily))
    )

Try / catch

try:
    validate_state(state)
except StarHistoryError as exc:
    if "reconstruction stars must be strictly increasing" in str(exc):
        # rebuild daily as cumulative totals from deltas, then re-validate
        ...

Prevention

When it happens

Trigger: validate_state(state) where daily[i]['stars'] <= daily[i-1]['stars'] for i > 0 — e.g. two consecutive days both at 100, or a decreasing value from misordered aggregation.

Common situations: Writing per-day deltas instead of cumulative totals; merging states and averaging/overwriting totals; GitHub pagination issues that dropped stars between fetches.

Related errors


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