{"record":{"id":"6a00ed9e91ffc9a0","repo":"666ghj/MiroFish","slug":"first-reconstruction-point-must-have-stars","errorCode":null,"errorMessage":"first reconstruction point must have stars","messagePattern":"first reconstruction point must have stars","errorType":"exception","errorClass":"StarHistoryError","httpStatus":null,"severity":"error","filePath":"scripts/star_history.py","lineNumber":413,"sourceCode":"\n    previous_day: date | None = None\n    previous_stars = 0\n    for index, raw_point in enumerate(daily):\n        if not isinstance(raw_point, dict):\n            raise StarHistoryError(\"reconstruction point must be an object\")\n        _expect_keys(raw_point, {\"date\", \"stars\"}, \"reconstruction point\")\n        raw_date = raw_point[\"date\"]\n        if not isinstance(raw_date, str):\n            raise StarHistoryError(\"reconstruction date must be a string\")\n        try:\n            point_day = date.fromisoformat(raw_date)\n        except ValueError as exc:\n            raise StarHistoryError(\"reconstruction date is invalid\") from exc\n        if point_day.isoformat() != raw_date:\n            raise StarHistoryError(\"reconstruction date is not canonical\")\n        stars = _strict_non_negative_int(raw_point[\"stars\"], \"reconstruction stars\")\n        if index == 0 and stars <= 0:\n            raise StarHistoryError(\"first reconstruction point must have stars\")\n        if previous_day is not None and point_day <= previous_day:\n            raise StarHistoryError(\"reconstruction dates must be strictly increasing\")\n        if index > 0 and stars <= previous_stars:\n            raise StarHistoryError(\"reconstruction stars must be strictly increasing\")\n        if point_day >= generated_at.date():\n            raise StarHistoryError(\"reconstruction must contain only completed UTC dates\")\n        previous_day = point_day\n        previous_stars = stars\n\n    snapshots = state[\"snapshots\"]\n    if not isinstance(snapshots, list):\n        raise StarHistoryError(\"snapshots must be a list\")\n    previous_snapshot: datetime | None = None\n    first_snapshot: datetime | None = None\n    for raw_snapshot in snapshots:\n        if not isinstance(raw_snapshot, dict):\n            raise StarHistoryError(\"snapshot must be an object\")\n        _expect_keys(raw_snapshot, {\"at\", \"stars\"}, \"snapshot\")","sourceCodeStart":395,"sourceCodeEnd":431,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/scripts/star_history.py#L395-L431","documentation":"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.","triggerScenarios":"validate_state(state) where daily[0]['stars'] is 0 (negative values are already rejected by _strict_non_negative_int).","commonSituations":"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.","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"],"exampleFix":"// before\n\"daily\": [{\"date\": \"2024-01-01\", \"stars\": 0}, {\"date\": \"2024-01-02\", \"stars\": 5}]\n// after\n\"daily\": [{\"date\": \"2024-01-02\", \"stars\": 5}]","handlingStrategy":"validation","validationCode":"daily = [p for p in daily if not (p is daily[0] and p[\"stars\"] == 0)]\ndaily = daily[next((i for i, p in enumerate(daily) if p[\"stars\"] > 0), len(daily)):]","typeGuard":"def first_point_has_stars(daily: list) -> bool:\n    return not daily or daily[0][\"stars\"] > 0","tryCatchPattern":"try:\n    validate_state(state)\nexcept StarHistoryError as exc:\n    if \"first reconstruction point must have stars\" in str(exc):\n        # strip leading zero-star days, then re-validate\n        ...","preventionTips":["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"],"tags":["validation","state-file","data-integrity"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}