FuelLabs/sway · error
failed to write lock file: {}
Error message
failed to write lock file: {} What it means
The new Forc.lock serialized fine but fs::write(lock_path, string) failed; {} is the io::Error. The lock could not be persisted to disk: permission denied on the directory, read-only filesystem/mount, disk full, or lock_path colliding with a directory.
Source
Thrown at forc-pkg/src/pkg.rs:753
"The lock file {} needs to be updated (Cause: {}) \
but --locked was passed to prevent this.",
lock_path.to_string_lossy(),
cause,
);
}
println_action_green(
"Creating",
&format!("a new `Forc.lock` file. (Cause: {cause})"),
);
let member_names = manifests
.values()
.map(|manifest| manifest.project.name.to_string())
.collect();
crate::lock::print_diff(&member_names, &lock_diff);
let string = toml::ser::to_string_pretty(&new_lock)
.map_err(|e| anyhow!("failed to serialize lock file: {}", e))?;
fs::write(lock_path, string)
.map_err(|e| anyhow!("failed to write lock file: {}", e))?;
debug!(" Created new lock file at {}", lock_path.display());
}
Ok(plan)
}
/// Produce an iterator yielding all contract dependencies of given node in the order of
/// compilation.
pub fn contract_dependencies(&self, node: NodeIx) -> impl Iterator<Item = NodeIx> + '_ {
let graph = self.graph();
let connected: HashSet<_> = Dfs::new(graph, node).iter(graph).collect();
self.compilation_order()
.iter()
.cloned()
.filter(move |&n| n != node)
.filter(|&n| {
graph
.edges_directed(n, Direction::Incoming)View on GitHub (pinned to 47e5e902fa)
Solutions
- Check write permission on the project directory (chmod u+w / chown) and that Forc.lock is a file, not a directory.
- Free disk space or raise the quota if the io error is No space left on device.
- Mount the workspace read-write in CI/Docker, or pre-generate the lock in a writable step.
Example fix
# before: read-only mount in CI # - run: forc build # volumeMounts: readOnly: true # after: write the lock in a writable stage - run: forc build docker run -v $PWD:/src -w /src ghcr.io/fuellabs/forc:latest forc build
Defensive patterns
Strategy: validation
Validate before calling
fn dir_is_writable(dir: &std::path::Path) -> bool {
let probe = dir.join(".forc_write_probe");
std::fs::write(&probe, b"").is_ok() && std::fs::remove_file(&probe).is_ok()
}
// check the project dir before building so the lock can be persisted Prevention
- Run builds from directories your user can write to.
- Mount CI workspaces read-write, or generate the lock in a writable stage.
- Watch disk space on build agents; Forc.lock writes fail on ENOSPC.
When it happens
Trigger: Building in a directory the process cannot write (root-owned, chmod 555); Docker/CI read-only volume; ENOSPC; a stray directory named Forc.lock.
Common situations: Running forc via sudo-created project dirs; CI sandbox with read-only source mounts; full disks or quotas on build agents.
Related errors
- failed to init repo at \"{}\": {}
- failed to read {}: {}
- failed to write toml file: {}
- failed to read manifest at {:?}: {}
- Cannot get parent dir of {:?}
AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16).
Data as JSON: /api/errors/e6d4611b23611f07.
Report an issue: GitHub.