Hmbown/CodeWhale · error · std::io::Error

session file missing parseable `metadata` block

Error message

session file missing parseable `metadata` block

What it means

Returned as io::ErrorKind::InvalidData when the session manager loads a session file whose top-level `metadata` block cannot be parsed. The loader first tries to extract metadata from an already-read prefix, then reads the remainder of the file and retries with the full buffer; this error means both attempts failed. The file on disk is therefore genuinely truncated or its metadata record is corrupted beyond what extract_top_level_metadata accepts.

Source

Thrown at crates/tui/src/session_manager.rs:1661

        const PREFIX_BYTES: usize = 64 * 1024;
        let mut file = fs::File::open(path)?;
        let mut buf = Vec::with_capacity(PREFIX_BYTES);
        file.by_ref()
            .take(PREFIX_BYTES as u64)
            .read_to_end(&mut buf)?;

        if let Some(metadata) = extract_top_level_metadata(&buf) {
            return Ok(metadata);
        }

        // Metadata wasn't extractable from the prefix (truncated mid-block,
        // unusual key ordering, etc.). Read the rest and try again with the
        // full buffer before giving up.
        let mut rest = Vec::new();
        file.read_to_end(&mut rest)?;
        buf.extend_from_slice(&rest);
        extract_top_level_metadata(&buf).ok_or_else(|| {
            std::io::Error::new(
                std::io::ErrorKind::InvalidData,
                "session file missing parseable `metadata` block",
            )
        })
    }

    /// Delete a session by ID
    pub fn delete_session(&self, id: &str) -> std::io::Result<()> {
        let path = self.validated_session_path(id)?;
        self.save_session_goal(id, None)?;
        fs::remove_file(path)?;
        self.clear_session_boot_owner(id);
        let session_dir = self.sessions_dir.join(id.trim());
        if session_dir.exists() {
            fs::remove_dir_all(session_dir)?;
        }
        Ok(())
    }

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Restore the affected session file from a backup or the previous synced copy
  2. If the session is disposable, delete or move the file out of the sessions directory so the manager regenerates a clean one
  3. Check free disk space and filesystem health to stop ongoing truncation during saves
  4. If the metadata line looks well-formed but still fails extraction, preserve the file and report a bug against extract_top_level_metadata

Example fix

// before
let meta = manager.session_metadata(id)?; // one bad file aborts the whole listing

// after
let meta = match manager.session_metadata(id) {
    Ok(m) => m,
    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => continue, // skip corrupt file, keep listing
    Err(e) => return Err(e),
};
Defensive patterns

Strategy: try-catch

Validate before calling

let raw = std::fs::read_to_string(&path)?;
let looks_complete = raw.lines().any(|l| l.contains("\"metadata\""));
if !looks_complete {
    // quarantine the file before the session loader rejects it
    let _ = std::fs::rename(&path, path.with_extension("corrupt"));
}

Type guard

fn is_unparseable_session_metadata(e: &std::io::Error) -> bool {
    e.kind() == std::io::ErrorKind::InvalidData
        && e.to_string().contains("missing parseable `metadata` block")
}

Try / catch

match manager.load_session(id) {
    Ok(s) => Ok(Some(s)),
    Err(e) if is_unparseable_session_metadata(&e) => {
        tracing::warn!(%id, "skipping corrupt session file");
        Ok(None) // degrade gracefully, keep the session list usable
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Resuming or listing a session whose .jsonl file was truncated mid-write (process kill, power loss, disk full during save), or whose metadata line was hand-edited, reordered, or written by an incompatible older format, so neither the prefix parse nor the full-buffer re-parse succeeds.

Common situations: App crashed while saving a session; disk-full during session write; sessions directory partially copied between machines or mutated by sync/backup tools; session files from a much older Codewhale version after an upgrade.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/d1b583c50617d8c8. Report an issue: GitHub.