sinelaw/fresh · warning

Invalid calibration file

Error message

Invalid calibration file: {}

What it means

load_from_file reads a key calibration JSON file and deserializes it into CalibrationFile. If the JSON is present but fails serde parsing (wrong shape, unknown/missing fields, invalid values), it returns io::ErrorKind::InvalidData with 'Invalid calibration file: {serde error}'. A missing file is fine (defaults are used); only malformed content triggers this.

Solutions

  1. Validate/fix the JSON in the calibration file (run it through a JSON linter and compare against the CalibrationFile schema)
  2. Regenerate the calibration file (delete it — load_from_file falls back to Self::new() defaults when the file is absent)
  3. Check for a version mismatch: move the old file aside and let the current version recreate it
  4. Wrap loading so parse failure degrades to defaults with a logged warning

Example fix

// before
let translator = KeyTranslator::load_from_file(&path)?; // hard error on bad JSON
// after
let translator = KeyTranslator::load_from_file(&path).unwrap_or_else(|e| {
    log::warn!("calibration unusable ({e}); using defaults");
    KeyTranslator::new()
});
Defensive patterns

Strategy: fallback

Validate before calling

fn calibration_file_ok(path: &Path) -> bool {
    std::fs::read_to_string(path).ok()
        .and_then(|c| serde_json::from_str::<serde_json::Value>(&c).ok())
        .map(|v| v.get("version").is_some())
        .unwrap_or(false)
}

Try / catch

let translator = KeyTranslator::load_from_file(path)
    .or_else(|e| { log::warn!("calibration invalid: {e}"); Ok(KeyTranslator::new()) })?;

Prevention

When it happens

Trigger: Calling KeyTranslator::load_from_file(path) where path exists but contains invalid JSON, fields with wrong types, or a structure that does not match the current CalibrationFile schema (e.g. a file written by a different version).

Common situations: Hand-edited calibration file with a typo; calibration file written by an older/newer editor version whose schema changed; truncated or corrupted file after a crash during write.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13). Data as JSON: /api/errors/3508795c8dd1e835. Report an issue: GitHub.

Appendix: source

Thrown at crates/fresh-editor/src/input/key_translator.rs:267

    }

    /// Clear all translations
    pub fn clear(&mut self) {
        self.translations.clear();
    }

    /// Load translations from a JSON file
    ///
    /// Returns an empty translator if the file doesn't exist.
    /// Returns an error if the file exists but is invalid.
    pub fn load_from_file(path: &Path) -> Result<Self, std::io::Error> {
        if !path.exists() {
            return Ok(Self::new());
        }

        let content = std::fs::read_to_string(path)?;
        let file: CalibrationFile = serde_json::from_str(&content).map_err(|e| {
            std::io::Error::new(
                std::io::ErrorKind::InvalidData,
                format!("Invalid calibration file: {}", e),
            )
        })?;

        let mut translator = Self::new();
        for entry in file.translations {
            translator.translations.insert(entry.raw, entry.expected);
        }

        tracing::info!(
            "Loaded {} key translations from {}",
            translator.len(),
            path.display()
        );

        Ok(translator)
    }

View on GitHub (pinned to 67894ca546)