pkgxdev/pkgx · critical

unexpected error: install locking failed

Error message

unexpected error: install locking failed

What it means

During `install`, an exclusive advisory lock (`lock_exclusive`) is taken on a lockfile in a blocking task. The code treats lock failure as unrecoverable and calls `.expect("unexpected error: install locking failed")`, i.e. it panics rather than returning an error. This indicates the OS refused the flock on the install lockfile — not a concurrency wait, but an actual failure to acquire the lock.

Solutions

  1. Move the cellar (PKGX_DIR) onto a local filesystem that supports flock (ext4, apfs, ntfs)
  2. Retry the install — transient fd/EPERM conditions usually disappear on a rerun
  3. Check mount options of the cellar filesystem (`mount | grep <cellar>`) and remount without NFS if flock is unsupported
  4. Report a panic: this expect should ideally be a returned error rather than an abort

Example fix

// before
lockfile
    .lock_exclusive()
    .expect("unexpected error: install locking failed");
// after
lockfile
    .lock_exclusive()
    .context("install locking failed")?;
Defensive patterns

Strategy: retry

Validate before calling

fn cellar_supports_flock(cellar: &std::path::Path) -> bool {
    // probe: create a temp file and try an exclusive flock
    std::fs::OpenOptions::new().create(true).write(true)
        .open(cellar.join(".pkgx-flock-probe"))
        .ok()
        .and_then(|f| fs2::FileExt::try_lock_exclusive(&f).ok())
        .is_some()
}

Try / catch

// the lib panics here, so guard the process, not the error
// run installs in a wrapper that detects this panic and retries on local FS:
let status = cmd.status()?;
if !status.success() && output_contains("install locking failed") {
    eprintln!("cellar FS may not support flock; retrying on local disk");
    // switch PKGX_DIR to a local path and retry
}

Prevention

When it happens

Trigger: Calling `install()` when the lockfile descriptor cannot be flocked — typically a filesystem that doesn't support advisory locks (some network mounts, certain overlay/tmpfs setups, Windows FAT), or an fd that was already closed/invalid because try_clone or the underlying file failed.

Common situations: Installing into a cellar on NFS/CIFS/SMB shares that don't support flock, running in containers with exotic mount options, or low-level fd exhaustion causing lock_exclusive to fail unexpectedly.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


AI-assisted analysis of pkgxdev/pkgx@6de1d7e953 (2026-09-10). Data as JSON: /api/errors/1b5fb90de4cb4c43. Report an issue: GitHub.

Appendix: source

Thrown at crates/lib/src/install.rs:62

    #[cfg(windows)]
    let lockfile = OpenOptions::new()
        .read(true)
        .write(true)
        .create(true)
        .truncate(true)
        .open(shelf.join("lockfile"))?;
    #[cfg(not(windows))]
    let lockfile = OpenOptions::new()
        .read(true) // Open the directory in read-only mode
        .open(shelf.clone())?;

    task::spawn_blocking({
        let lockfile = lockfile.try_clone()?;
        move || {
            lockfile
                .lock_exclusive()
                .expect("unexpected error: install locking failed");
        }
    })
    .await?;

    let dst_path = cellar::dst(pkg, config);

    // did another instance of pkgx install us while we waited for the lock?
    // if so, we’re good: eject
    if dst_path.is_dir() {
        FileExt::unlock(&lockfile)?;
        return Ok(Installation {
            path: dst_path,
            pkg: pkg.clone(),
        });
    }

    let url = inventory::get_url(pkg, config);
    let client = build_client()?;

View on GitHub (pinned to 6de1d7e953)