666ghj/MiroFish · error · StarHistoryError
reconstruction must be an object
Error message
reconstruction must be an object
What it means
Raised by validate_state() in scripts/star_history.py when the 'reconstruction' field of the star-history JSON state file is not a JSON object (dict). The validator requires the whole state document to match an exact schema, and reconstruction must be a dict with exactly the keys 'method', 'generated_at', and 'daily'. This error means the shape is fundamentally wrong before any field-level checks run.
Source
Thrown at scripts/star_history.py:375
"history state",
)
if state["schema_version"] != 1 or type(state["schema_version"]) is not int:
raise StarHistoryError("unsupported history schema_version")
if state["repository"] != REPOSITORY:
raise StarHistoryError("history repository does not match configured repository")
if state["timezone"] != "UTC":
raise StarHistoryError("history timezone must be UTC")
if (
state["ongoing_interval_days"] != INTERVAL_DAYS
or type(state["ongoing_interval_days"]) is not int
):
raise StarHistoryError(
f"history interval must be exactly {INTERVAL_DAYS} days"
)
reconstruction = state["reconstruction"]
if not isinstance(reconstruction, dict):
raise StarHistoryError("reconstruction must be an object")
_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:View on GitHub (pinned to b5b53acc57)
Solutions
- Restore 'reconstruction' to a JSON object: {"method": ..., "generated_at": ..., "daily": [...]}
- If the file was hand-edited, re-run the generation step instead of editing state manually
- Check schema_version is 1 and the file matches the current script version's expected layout
Example fix
// before
"reconstruction": [{"date": "2024-01-01", "stars": 10}]
// after
"reconstruction": {
"method": "current_stargazers_starred_at",
"generated_at": "2024-01-02T00:00:00Z",
"daily": [{"date": "2024-01-01", "stars": 10}]
} Defensive patterns
Strategy: validation
Validate before calling
import json
state = json.loads(state_text)
rec = state.get("reconstruction")
assert isinstance(rec, dict), "reconstruction must be an object" Type guard
def is_reconstruction_object(value) -> bool:
return isinstance(value, dict) Try / catch
try:
validate_state(state)
except StarHistoryError as exc:
if "reconstruction must be an object" in str(exc):
# regenerate or reject the state file
... Prevention
- Only produce state files via the script's canonical writer (canonical_state_bytes)
- Never hand-edit the state JSON; regenerate instead
- Treat any externally received state file as untrusted and validate before use
When it happens
Trigger: Calling validate_state(state) or canonical_state_bytes(state) (which calls validate_state internally) on a state dict where state['reconstruction'] is a list, string, number, null, or is missing-adjacent (e.g. hand-edited state file where reconstruction was replaced by an array of points).
Common situations: Hand-editing the state JSON and replacing the reconstruction object with a bare array of {date, stars} points; consuming a state file produced by a different/older version of the script with a different schema; deserializing YAML/JSON where the nesting level was flattened by mistake.
Related errors
- history state must be a JSON object
- reconstruction.daily must be a list
- reconstruction point must be an object
- snapshots must be a list
- snapshot must be an object
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/dadda321c8dc0e5b.
Report an issue: GitHub.