{"record":{"id":"3624839803625942","repo":"666ghj/MiroFish","slug":"history-interval-must-be-exactly-interval-days-d","errorCode":null,"errorMessage":"history interval must be exactly {INTERVAL_DAYS} days","messagePattern":"history interval must be exactly (.+?) days","errorType":"exception","errorClass":"StarHistoryError","httpStatus":null,"severity":"error","filePath":"scripts/star_history.py","lineNumber":369,"sourceCode":"            \"repository\",\n            \"timezone\",\n            \"ongoing_interval_days\",\n            \"reconstruction\",\n            \"snapshots\",\n        },\n        \"history state\",\n    )\n    if state[\"schema_version\"] != 1 or type(state[\"schema_version\"]) is not int:\n        raise StarHistoryError(\"unsupported history schema_version\")\n    if state[\"repository\"] != REPOSITORY:\n        raise StarHistoryError(\"history repository does not match configured repository\")\n    if state[\"timezone\"] != \"UTC\":\n        raise StarHistoryError(\"history timezone must be UTC\")\n    if (\n        state[\"ongoing_interval_days\"] != INTERVAL_DAYS\n        or type(state[\"ongoing_interval_days\"]) is not int\n    ):\n        raise StarHistoryError(\n            f\"history interval must be exactly {INTERVAL_DAYS} days\"\n        )\n\n    reconstruction = state[\"reconstruction\"]\n    if not isinstance(reconstruction, dict):\n        raise StarHistoryError(\"reconstruction must be an object\")\n    _expect_keys(\n        reconstruction,\n        {\"method\", \"generated_at\", \"daily\"},\n        \"reconstruction\",\n    )\n    reconstruction_method = reconstruction[\"method\"]\n    if reconstruction_method not in {\n        \"current_stargazers_starred_at\",\n        \"aggregate_snapshot_only\",\n    }:\n        raise StarHistoryError(\"unsupported reconstruction method\")\n    generated_at = _parse_state_timestamp(","sourceCodeStart":351,"sourceCodeEnd":387,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/scripts/star_history.py#L351-L387","documentation":"validate_state requires ongoing_interval_days to equal the module constant INTERVAL_DAYS (13) and be a real int; a mismatch raises StarHistoryError(f'history interval must be exactly {INTERVAL_DAYS} days'). The interval defines the ongoing-snapshot cadence baked into the stored data, so changing it without rebuilding state would corrupt the timeline.","triggerScenarios":"A state file with ongoing_interval_days: 7 or 30 (written when INTERVAL_DAYS had a different value), a float like 13.0, or editing INTERVAL_DAYS in source while keeping old state.","commonSituations":"Tuning INTERVAL_DAYS in scripts/star_history.py (currently 13) and reusing an existing state file; merging state from a fork with a different cadence.","solutions":["Revert INTERVAL_DAYS to 13 if you want to keep the existing state","Or delete the state file and rebuild history after changing the interval — stored snapshots assume the old cadence and cannot be reused","Never edit ongoing_interval_days in the JSON by hand to match new code; the data would still be inconsistent"],"exampleFix":"# before (scripts/star_history.py)\nINTERVAL_DAYS = 13\n# changed to:\nINTERVAL_DAYS = 7  # but state still says 13\n\n# after\nINTERVAL_DAYS = 7\nrm state.json && python scripts/star_history.py  # full rebuild under the new cadence","handlingStrategy":"validation","validationCode":"interval = state.get(\"ongoing_interval_days\")\nif type(interval) is not int or interval != INTERVAL_DAYS:\n    raise StarHistoryError(f\"state interval {interval!r} != configured {INTERVAL_DAYS}; rebuild the state\")","typeGuard":"def state_interval_matches(state: object) -> TypeGuard[dict]:\n    return (\n        isinstance(state, dict)\n        and type(state.get(\"ongoing_interval_days\")) is int\n        and state[\"ongoing_interval_days\"] == INTERVAL_DAYS\n    )","tryCatchPattern":"try:\n    validate_state(state)\nexcept StarHistoryError as exc:\n    if \"history interval\" in str(exc):\n        regenerate_state_file()  # cadence changed; old snapshots are unusable\n    else:\n        raise","preventionTips":["Changing INTERVAL_DAYS requires deleting the state file and rebuilding — stored snapshots encode the old cadence","Never hand-edit ongoing_interval_days to match new code; the underlying data stays inconsistent"],"tags":["state-file","configuration","validation","star-history"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}