astrid-runtime/astrid · error

leftover capsule authority receipt has no file name

Error message

leftover capsule authority receipt has no file name: {}

What it means

When retiring a legacy capsule authority receipt, quarantine_legacy_authority_receipt moves the receipt file into a quarantine directory via fs::rename and needs the file's name to build the destination. A path without a final component (e.g. a root path or path ending in ..) makes this impossible, so it errors instead of silently mishandling the file.

Solutions

  1. Ensure the leftover receipt path points to an actual file with a name
  2. Recompute the path including its final component before calling install/cleanup
  3. Delete the stale leftover entry so quarantine is skipped
  4. Manually remove the receipt file if it's safe to retire
Defensive patterns

Strategy: type-guard

Validate before calling

fn quaraninable(path: &Path) -> bool {
    path.is_file() && path.file_name().is_some()
}

Type guard

fn has_file_name(path: &Path) -> bool {
    path.file_name().is_some()
}

Try / catch

match quarantine_legacy_authority_receipt(...) {
    Err(e) if e.to_string().contains("has no file name") => {
        eprintln!("receipt path is malformed; clean up the leftover entry manually");
    }
    other => other?,
}

Prevention

When it happens

Trigger: quarantine_legacy_authority_receipt is called (directly or via retire_one_leftover) with a receipt path that has no file_name — typically a path like "/" or a normalized path whose last component is missing.

Common situations: Path built by string concatenation losing the filename; directory passed instead of a file; stale registry entry pointing at a path that no longer resolves to a named file.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at crates/astrid-capsule-install/src/authority/leftover.rs:108

    Ok(Some((receipt, bytes)))
}

/// Move one leftover receipt out of the live authority directory.
pub(crate) fn quarantine_legacy_authority_receipt(
    home: &AstridHome,
    path: &Path,
) -> anyhow::Result<PathBuf> {
    let bytes = fs::read(path)
        .with_context(|| format!("read leftover capsule authority {}", path.display()))?;
    let quarantine_root = home.migrations_dir().join(QUARANTINE_DIR);
    astrid_core::platform_fs::ensure_private_directory(&quarantine_root).with_context(|| {
        format!(
            "secure leftover authority quarantine {}",
            quarantine_root.display()
        )
    })?;
    let file_name = path.file_name().ok_or_else(|| {
        anyhow::anyhow!(
            "leftover capsule authority receipt has no file name: {}",
            path.display()
        )
    })?;
    let destination = unique_quarantine_path(&quarantine_root, file_name)?;
    fs::rename(path, &destination).with_context(|| {
        format!(
            "quarantine leftover capsule authority {} to {}",
            path.display(),
            destination.display()
        )
    })?;
    if let Some(parent) = path.parent() {
        sync_authority_directory(parent)?;
    }
    let preserved = fs::read(&destination).with_context(|| {
        format!(
            "read quarantined capsule authority {}",

View on GitHub (pinned to affd8760f4)