FuelLabs/sway · error · anyhow::Error
failed to serialize lock file: {}
Error message
failed to serialize lock file: {} What it means
After `forc update` recomputes the dependency graph and builds a new Lock from it, the final step serializes with toml::ser::to_string_pretty; failure is wrapped as "failed to serialize lock file: <error>". Serialization fails only if the Lock graph contains data not representable in TOML (e.g. invalid string keys/values such as control characters in names), which normally indicates malformed manifest input.
Source
Thrown at forc/src/ops/forc_update.rs:55
let manifest = ManifestFile::from_dir(this_dir)?;
let lock_path = lock_path(manifest.dir());
let old_lock = Lock::from_path(&lock_path).ok().unwrap_or_default();
let offline = false;
let member_manifests = manifest.member_manifests()?;
let ipfs_node = command.ipfs_node.unwrap_or_default();
let new_plan = pkg::BuildPlan::from_manifests(&member_manifests, offline, &ipfs_node)?;
let new_lock = Lock::from_graph(new_plan.graph());
let diff = new_lock.diff(&old_lock);
let member_names = member_manifests
.values()
.map(|manifest| manifest.project.name.clone())
.collect();
lock::print_diff(&member_names, &diff);
// If we're not only `check`ing, write the updated lock file.
if !check {
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))?;
info!(" Created new lock file at {}", lock_path.display());
} else {
info!(" `--check` enabled: `Forc.lock` was not changed");
}
Ok(())
}
View on GitHub (pinned to 47e5e902fa)
Solutions
- Back up and delete Forc.lock, then rerun `forc update` to regenerate it from scratch
- Inspect member and dependency Forc.toml files for malformed names/paths and fix them
- Update forc — serialization failures after dependency-handling refactors are usually fixed in patch releases
Example fix
# before forc update # failed to serialize lock file: ... # after mv Forc.lock Forc.lock.bak && forc update
Defensive patterns
Strategy: fallback
Validate before calling
// Before forc update: back up the lock so a serialization failure is recoverable,
// and sanity-check that member manifests parse.
std::fs::copy("Forc.lock", "Forc.lock.bak")?;
for m in member_manifest_paths() {
PackageManifest::from_file(m)
.map_err(|e| anyhow::anyhow!("malformed manifest {m}: {e}"))?;
} Try / catch
match run_forc_update(dir) {
Ok(()) => Ok(()),
Err(e) if e.to_string().contains("failed to serialize lock file") => {
// fallback: regenerate the lock from scratch, then retry once
std::fs::remove_file(dir.join("Forc.lock")).ok();
run_forc_update(dir)
}
Err(e) => Err(e),
} Prevention
- Keep Forc.lock under version control so a failed update never destroys known-good state
- Avoid hand-editing Forc.toml dependency names/paths with unusual characters
- After upgrading forc, run `forc update` once in a clean checkout before batch-updating workspaces
When it happens
Trigger: `forc update` (without --check) on a workspace where some dependency name, path-derived key, or version string contains characters TOML cannot represent, or where a partial graph produced inconsistent state.
Common situations: Corrupted or hand-edited Forc.toml entries (odd package names/paths), dependencies whose repository-derived identifiers contain unusual characters, or forc bugs after major dependency-handling changes.
Related errors
- lock file did not exist
- Invalid lock: {}
- failed to read {}: {}
- invalid 'source' entry for package {} lock: {:?}
- failed to parse dependency "{}": {}
AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16).
Data as JSON: /api/errors/26f4fe86981f1215.
Report an issue: GitHub.