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.

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)

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.