Hmbown/CodeWhale · error

{error}

Error message

{error}

What it means

Serializing the archive manifest JSON failed, and the error was converted into an io::Error with InvalidData. The manifest embeds the session metadata and tar member list; serialization only fails if the data cannot be represented as JSON (rare) or the serializer errors mid-write.

Solutions

  1. Check the embedded {error} text for the serialization failure detail.
  2. Re-export after regenerating the session metadata with the current app version.
  3. If a custom field type fails to serialize, fix its Serialize implementation or drop it from the manifest.

Example fix

// before: non-string map keys in metadata
tags: HashMap<i64, String>
// after
tags: BTreeMap<String, String>
Defensive patterns

Strategy: try-catch

Validate before calling

serde_json::to_value(&session.metadata).map_err(|e| format!("metadata not serializable: {e}"))?;

Try / catch

match write_session_archive(&s, dir, out, o) { Err(e) if e.kind() == io::ErrorKind::InvalidData => eprintln!("manifest serialization failed: {e}; regenerate session metadata"), r => r?, }

Prevention

When it happens

Trigger: Calling write_session_archive (crates/tui/src/session_export.rs:234) when serde_json serialization of the ArchiveManifest returns Err — e.g. session metadata containing non-serializable values or a map with non-string keys introduced by a format change.

Common situations: Session metadata produced by a different version with incompatible field types; hand-edited or corrupted metadata loaded into SavedSession; custom Serialize impl that errors.

Understand the failure class

Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/c1bc0f596e013b9e. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/session_export.rs:234

            // Parent directories and the leaf are opened without following links.
            // Stream this handle directly; never reopen a validated path.
            let mut file = WorkspaceFile::open(root, relative, false)?.open_file()?;
            append_member(
                &mut tar,
                name,
                MemberContents::File(&mut file),
                &mut summary.members,
            )?;
        }
        let manifest_json = serde_json::to_string_pretty(&ArchiveManifest {
            archive_format_version: SESSION_ARCHIVE_FORMAT_VERSION,
            generator: env!("CARGO_PKG_NAME"),
            generator_version: env!("CARGO_PKG_VERSION"),
            exported_at: Utc::now().to_rfc3339(),
            session: session.metadata.clone(),
            members: summary.members.clone(),
        })
        .map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;
        append_member(
            &mut tar,
            ARCHIVE_MANIFEST_MEMBER,
            MemberContents::Bytes(manifest_json.as_bytes()),
            &mut Vec::new(),
        )?;
        let encoder = tar.into_inner()?;
        let file = encoder.finish()?;
        file.flush()?;
        file.sync_all()?;
    }
    if options.overwrite {
        temp.persist(output)
    } else {
        temp.persist_noclobber(output)
    }
    .map_err(|error| {
        if error.error.kind() == io::ErrorKind::AlreadyExists {

View on GitHub (pinned to 73e0f67d83)