tonhowtf/omniget · error · std::io::Error
e.to_string()
Error message
e.to_string()
What it means
In save_state, after resolving the path, the state is serialized with serde_json::to_string_pretty. Serialization failures (the AnonymousCookieState contains a value serde cannot serialize, e.g. a map with non-string keys or a NaN float) are converted into an io::Error of Kind::InvalidData whose message is just e.to_string(). This aborts writing the anonymous cookie state.
Solutions
- Inspect the inner serde error (the io error's message) to find which field failed to serialize.
- Validate state values before saving — replace NaN/Infinity numbers with defaults (0 or None as Option).
- Change offending fields to serializable types (Option<f64>, String keys in maps).
- Use #[serde(default)] on new fields so old-state compatibility is maintained.
Example fix
// before expires_at: f64, // can hold NaN // after #[serde(default)] expires_at: Option<f64>, // None instead of NaN; always serializes
Defensive patterns
Strategy: validation
Validate before calling
fn state_serializable(state: &AnonymousCookieState) -> bool {
serde_json::to_string(state).is_ok()
}
// call before save_state
if !state_serializable(&state) { log::warn!("cookie state not serializable; skipping save"); } Try / catch
match save_state(&state) {
Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {
log::warn!("cookie state serialization failed: {e}");
}
r => r?,
} Prevention
- Keep numeric fields Option-wrapped so NaN/Infinity never enters the state
- Add #[serde(default)] to new fields for backward compatibility
- Test round-trip serialization of AnonymousCookieState in CI
- Sanitize server-derived values before building the state struct
When it happens
Trigger: Calling save_state (via bootstrap_anonymous) with an AnonymousCookieState whose fields fail serde_json serialization: unexpected non-string map keys, unserializable numeric values (NaN/Infinity floats from timestamps/tokens), or a struct field type change without updating serialization.
Common situations: A struct refactor added a field type serde_json can't handle; corrupted in-memory state built from bad server responses (NaN expiry); version drift where old cached structs no longer match the serde derive.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- app_data_dir unavailable
- e.to_string()
- All playlist item(s) failed to download. First error
- api client init failed
- api client init failed
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/282fd760de8714cf.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/platforms/bilibili/cookie.rs:70
Some(p) => p,
None => return AnonymousCookieState::default(),
};
let content = match std::fs::read_to_string(&path) {
Ok(c) => c,
Err(_) => return AnonymousCookieState::default(),
};
serde_json::from_str(&content).unwrap_or_default()
}
pub fn save_state(state: &AnonymousCookieState) -> std::io::Result<()> {
let path = meta_file_path().ok_or_else(|| {
std::io::Error::new(std::io::ErrorKind::Other, "app_data_dir unavailable")
})?;
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
let serialized = serde_json::to_string_pretty(state)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string()))?;
std::fs::write(path, serialized)
}
pub async fn ensure_fresh() -> Result<AnonymousCookieState> {
let cached = load_state();
if cached.is_fresh() {
write_netscape_for_anonymous(&cached).ok();
return Ok(cached);
}
bootstrap_anonymous().await
}
pub async fn bootstrap_anonymous() -> Result<AnonymousCookieState> {
let ua = super::api::DEFAULT_USER_AGENT;
let now_ms = now_ms();
let uuid = gen_uuid_b_lsid();
let b_lsid = gen_b_lsid();
let b_nut = now_ms.to_string();View on GitHub (pinned to 8600b91f42)