flxzt/rnote · error
store snapshot has no value `chrono_counter`.
Error message
store snapshot has no value `chrono_counter`.
What it means
The maj0min5patch9 -> maj0min6 migration requires `store_snapshot.chrono_counter` to exist, as it becomes `engine_snapshot.chrono_counter` in the new format. This error is thrown when that key is missing from the store snapshot object after the previous keys were removed successfully.
Solutions
- Inspect the extracted JSON and add `"chrono_counter": 0` (or the appropriate integer) to the store snapshot.
- Restore the document from a backup or autosave copy.
- Re-save the file with the rnote version matching its stored format version.
- If migrating many files, pre-process them with a script that inserts a default `chrono_counter` before conversion.
Example fix
// before
"store_snapshot": { "stroke_components": [], "chrono_components": [] }
// after
"store_snapshot": { "stroke_components": [], "chrono_components": [], "chrono_counter": 0 } Defensive patterns
Strategy: validation
Validate before calling
// validate before migration
fn has_chrono_counter(doc: &serde_json::Value) -> bool {
doc["store_snapshot"].get("chrono_counter").map_or(false, |v| v.is_u64() || v.is_i64())
} Type guard
fn store_snapshot_has(doc: &serde_json::Value, key: &str) -> bool {
doc["store_snapshot"].get(key).is_some()
} Try / catch
match RnoteFileMaj0Min6::try_from(prev) {
Ok(migrated) => /* use migrated */,
Err(e) if e.to_string().contains("no value `chrono_counter`") => {
// insert a default chrono_counter (e.g. 0) and retry
}
Err(e) => return Err(e),
} Prevention
- Always serialize `chrono_counter` with the store snapshot.
- Pre-fill default values (0) for missing counters in custom tooling that writes .rnote files.
- Validate the full set of required store snapshot keys before migration.
- Keep a backup copy before version upgrades.
When it happens
Trigger: Running `RnoteFileMaj0Min6::try_from` on a file whose store snapshot contains `stroke_components` and `chrono_components` but no `chrono_counter` key.
Common situations: Files hand-edited with the counter removed, corruption during save, or files from a fork that did not track the chrono counter.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- brushstroke has no value `path`.
- store snapshot has no value `stroke_components`.
- store snapshot has no value `chrono_components`.
- document has no value `layout`.
- engine snapshot does not contain 'stroke_components'.
AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08).
Data as JSON: /api/errors/c0f662799c0d5e41.
Report an issue: GitHub.
Appendix: source
Thrown at crates/rnote-engine/src/fileformats/rnoteformat/maj0min6.rs:41
engine_snapshot.insert(String::from("document"), value.document);
engine_snapshot.insert(
String::from("stroke_components"),
store_snapshot
.remove("stroke_components")
.ok_or_else(|| anyhow!("store snapshot has no value `stroke_components`."))?,
);
engine_snapshot.insert(
String::from("chrono_components"),
store_snapshot
.remove("chrono_components")
.ok_or_else(|| anyhow!("store snapshot has no value `chrono_components`."))?,
);
engine_snapshot.insert(
String::from("chrono_counter"),
store_snapshot
.remove("chrono_counter")
.ok_or_else(|| anyhow!("store snapshot has no value `chrono_counter`."))?,
);
Ok(Self {
engine_snapshot: engine_snapshot.into(),
})
}
}
View on GitHub (pinned to bbc5354502)