FuelLabs/sway · error

failed to serialize lock file: {}

Error message

failed to serialize lock file: {}

What it means

While persisting a freshly generated lock, toml::ser::to_string_pretty(&new_lock) failed; {} is the serde error. The in-memory lock could not be represented as TOML, which the Lock model normally guarantees - so this almost always indicates a bug in forc-pkg or pathological package metadata (e.g. a dependency key that is not TOML-representable) rather than ordinary misconfiguration.

Source

Thrown at forc-pkg/src/pkg.rs:751

            if locked {
                bail!(
                    "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| {

View on GitHub (pinned to 47e5e902fa)

Solutions

  1. Inspect the printed serde error to see which value failed to serialize.
  2. Run 'forc update' to regenerate the lock from scratch.
  3. Simplify unusual package/dependency names and retry.
  4. If it reproduces with a clean state, report it to FuelLabs/sway with the manifest and full error text.
Defensive patterns

Strategy: try-catch

Try / catch

match forc_pkg::pkg::BuildPlan::from_lock_and_manifests(&lock_path, manifests, locked, offline, &ipfs_node) {
    Ok(plan) => { /* ... */ }
    Err(e) if e.to_string().starts_with("failed to serialize lock file") => {
        // not user-fixable config: capture state and report to FuelLabs/sway
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: A package or dependency name containing values the TOML serializer rejects; an internal invariant violation producing a non-serializable Lock; essentially only reachable through exotic inputs or a forc-pkg regression.

Common situations: Rare in practice; seen with unusual package names or after upgrading to a forc version with a lock-schema bug.

Related errors


AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16). Data as JSON: /api/errors/1f6c3df1d33a02dc. Report an issue: GitHub.