666ghj/MiroFish · error · StarHistoryError
aggregate-only history cannot contain reconstructed dates
Error message
aggregate-only history cannot contain reconstructed dates
What it means
Raised by validate_state() when reconstruction.method is 'aggregate_snapshot_only' yet the daily list is non-empty. An aggregate-only history intentionally carries no reconstructed daily points; its star history is derived purely from snapshots. Mixing both is treated as a corrupt or contradictory state.
Source
Thrown at scripts/star_history.py:394
_expect_keys(
reconstruction,
{"method", "generated_at", "daily"},
"reconstruction",
)
reconstruction_method = reconstruction["method"]
if reconstruction_method not in {
"current_stargazers_starred_at",
"aggregate_snapshot_only",
}:
raise StarHistoryError("unsupported reconstruction method")
generated_at = _parse_state_timestamp(
reconstruction["generated_at"], "reconstruction.generated_at"
)
daily = reconstruction["daily"]
if not isinstance(daily, list):
raise StarHistoryError("reconstruction.daily must be a list")
if reconstruction_method == "aggregate_snapshot_only" and daily:
raise StarHistoryError("aggregate-only history cannot contain reconstructed dates")
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:View on GitHub (pinned to b5b53acc57)
Solutions
- Either set method to 'current_stargazers_starred_at' (keeping the daily points), or set daily to [] for aggregate_snapshot_only
- Do not hand-switch methods on an existing state file; regenerate it with the intended mode
Example fix
// before
"method": "aggregate_snapshot_only",
"daily": [{"date": "2024-01-01", "stars": 10}]
// after
"method": "aggregate_snapshot_only",
"daily": [] Defensive patterns
Strategy: validation
Validate before calling
method = state["reconstruction"]["method"]
daily = state["reconstruction"]["daily"]
if method == "aggregate_snapshot_only" and daily:
state["reconstruction"]["daily"] = [] # or switch method if daily is authoritative Type guard
def is_method_daily_consistent(method: str, daily: list) -> bool:
return not (method == "aggregate_snapshot_only" and daily) Try / catch
try:
validate_state(state)
except StarHistoryError as exc:
if "aggregate-only history cannot contain reconstructed dates" in str(exc):
# decide which source is authoritative and rebuild the state
... Prevention
- Never change reconstruction.method on an existing state file by hand
- Regenerate state in the intended mode instead of transforming it
- Add an invariant test: aggregate_snapshot_only implies empty daily
When it happens
Trigger: validate_state(state) with method="aggregate_snapshot_only" and at least one entry in reconstruction.daily.
Common situations: Switching a state file from the reconstructed method to aggregate_snapshot_only by editing only the method field while leaving daily data in place; merging states from two runs that used different methods.
Related errors
- {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
- unsupported history schema_version
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/9c553524270f050f.
Report an issue: GitHub.