astrid-runtime/astrid · error

legacy capsule authority entry has a non-UTF-8 name: {}

Error message

legacy capsule authority entry has a non-UTF-8 name: {}

What it means

legacy_authority_receipt_status requires receipt file names to be valid UTF-8 so they can be parsed into status categories (pending, unmatched, etc.). If path.file_name() is not representable as UTF-8, the library throws this error rather than guessing how to classify the entry.

Source

Thrown at crates/astrid-capsule-install/src/authority/status.rs:79

        .collect::<anyhow::Result<BTreeSet<_>>>()?;
    let mut status = LegacyAuthorityReceiptStatus::default();
    let mut entries = std::fs::read_dir(&directory)
        .with_context(|| format!("read legacy capsule authority root {}", directory.display()))?
        .collect::<Result<Vec<_>, _>>()
        .with_context(|| format!("read legacy capsule authority root {}", directory.display()))?;
    entries.sort_by_key(std::fs::DirEntry::file_name);
    for entry in entries {
        let path = entry.path();
        let metadata = std::fs::symlink_metadata(&path)
            .with_context(|| format!("inspect legacy capsule authority {}", path.display()))?;
        if metadata.file_type().is_symlink() || !metadata.is_file() {
            bail!(
                "legacy capsule authority root contains a non-regular entry: {}",
                path.display()
            );
        }
        let Some(name) = path.file_name().and_then(|name| name.to_str()) else {
            bail!(
                "legacy capsule authority entry has a non-UTF-8 name: {}",
                path.display()
            );
        };
        if name.ends_with(".pending") {
            status.pending.push(path);
        } else if name.ends_with(".previous") {
            status.previous.push(path);
        } else if !path
            .extension()
            .is_some_and(|extension| extension.eq_ignore_ascii_case("json"))
            || !permitted.contains(&path)
        {
            status.unknown_active.push(path);
        }
    }
    Ok(status)
}

View on GitHub (pinned to affd8760f4)

Solutions

  1. Identify the non-UTF-8 entry with ls -b (or find . -name '*\x*') and rename it to a UTF-8 name
  2. If the entry is junk, delete it manually, then re-run the status command
  3. Recreate receipts via the tool itself so names are generated with valid UTF-8
  4. Fix the transfer path/locale that produced the raw-byte name and re-copy with convmv -t UTF-8

Example fix

// before
$ ls ~/.astrid/authority
receipt\xff.json
// after
$ mv $'receipt\xff.json' receipt-fixed.json
$ astrid authority status
Defensive patterns

Strategy: validation

Validate before calling

for entry in std::fs::read_dir(root)?.filter_map(Result::ok) {
    if entry.file_name().to_str().is_none() {
        eprintln!("non-UTF-8 name: {:?}", entry.file_name());
    }
}

Type guard

fn has_utf8_name(p: &Path) -> bool {
    p.file_name().and_then(|n| n.to_str()).is_some()
}

Prevention

When it happens

Trigger: Calling legacy_capsule_authority_status (or its test callers) when a file in the authority root has a non-UTF-8 name (status.rs:79) — typically a file created with raw bytes in its name, e.g. by a tool using a different locale/encoding or a corrupted/carefully crafted name.

Common situations: Files copied from a non-UTF-8 filesystem (legacy Samba share, old FAT volume) into the authority directory; scripts creating receipts with escaped byte names; download tools preserving hostile names.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/88a8f07322a6346a. Report an issue: GitHub.