astrid-runtime/astrid · error · InviteStoreError
(wrapped UTF-8 conversion error from invite store bytes)
Error message
(wrapped UTF-8 conversion error from invite store bytes)
What it means
The invite store file on disk is read as raw bytes and must be valid UTF-8 (TOML). If `str::from_utf8` fails, the underlying UTF-8 error is wrapped in an `io::Error` with `InvalidData` and rethrown as an `InviteStoreError::Io`.
Solutions
- Check the file encoding (`file` command) and convert it to UTF-8, or restore a known-good copy.
- Delete the corrupt store file so the store starts empty (pending invites will need re-issuing).
- Fix the tooling or editor that wrote non-UTF-8 content to the store.
Example fix
# before iconv -f UTF-16 -t UTF-8 corrupt.toml > invites.toml # wrong source encoding # after iconv -f UTF-16LE -t UTF-8 corrupt.toml > invites.toml && astrid invites list
Defensive patterns
Strategy: validation
Validate before calling
let bytes = std::fs::read(store_path)?;
if std::str::from_utf8(&bytes).is_err() {
eprintln!("invite store is not valid UTF-8; restore or remove it");
return Err(MyError::CorruptStore);
} Type guard
fn is_utf8_file(p: &std::path::Path) -> bool {
std::fs::read(p).map(|b| std::str::from_utf8(&b).is_ok()).unwrap_or(false)
} Try / catch
match store.load() {
Err(InviteStoreError::Io(e)) if e.kind() == std::io::ErrorKind::InvalidData => {
warn!("corrupt/non-UTF-8 invite store, starting empty");
InviteStore::empty()
}
other => other?,
} Prevention
- Edit invite store files only with UTF-8-safe editors (`:set encoding=utf-8` in vim).
- Back up the store before manual edits.
- Never copy binary files over the store path; verify with `file` before replacing.
When it happens
Trigger: Calling `load` → `load_from_disk` when the invite store file contains bytes that are not valid UTF-8 (binary content, wrong encoding, corruption).
Common situations: The store file was edited with a tool that saved UTF-16 or Latin-1; the file got corrupted or truncated mid-write; a binary file was copied over the store path.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- invalid utf-8 sequence of
- capsule path is not valid UTF-8
- layout destination path is not portable UTF-8
- legacy capsule authority entry has a non-UTF-8 name
- legacy principal-home source
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/12b7f77503796a4c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-kernel/src/invite/mod.rs:529
{
let _ = &self.path;
return Ok(Vec::new());
}
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
{
self.load_from_disk()
}
}
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
fn load_from_disk(&self) -> Result<Vec<Invite>, InviteStoreError> {
let bytes = match std::fs::read(&self.path) {
Ok(b) => b,
Err(e) if e.kind() == std::io::ErrorKind::NotFound => return Ok(Vec::new()),
Err(e) => return Err(InviteStoreError::Io(e)),
};
let text = std::str::from_utf8(&bytes).map_err(|e| {
InviteStoreError::Io(std::io::Error::new(std::io::ErrorKind::InvalidData, e))
})?;
if text.trim().is_empty() {
if let Err(error) = self.save_to_disk(&[]) {
warn!(
path = %self.path.display(),
%error,
"could not normalize empty invite store"
);
}
return Ok(Vec::new());
}
let probe: SchemaProbe = toml::from_str(text).map_err(InviteStoreError::Toml)?;
if probe.schema_version > STORE_SCHEMA_VERSION {
return Err(InviteStoreError::Io(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"invite store schema {} is newer than supported schema {STORE_SCHEMA_VERSION}",
probe.schema_versionView on GitHub (pinned to affd8760f4)