FuelLabs/sway · error

invalid 'source' entry for package {} lock: {:?}

Error message

invalid 'source' entry for package {} lock: {:?}

What it means

While converting a parsed Forc.lock back into a package graph (Lock::to_graph), every package entry's source string is parsed into a source::Pinned value (git+https://...#commit, path+..., registry+...). If the string matches no known pinned-source format, this error names the package and echoes the underlying parse error, pointing at that package entry in the lock.

Source

Thrown at forc-pkg/src/lock.rs:191

    /// Given a `Lock` loaded from a `Forc.lock` file, produce the graph of pinned dependencies.
    pub fn to_graph(&self) -> Result<pkg::Graph> {
        let mut graph = pkg::Graph::new();

        // Track the names which need to be disambiguated in the dependency list.
        let names = self.package.iter().map(|pkg| &pkg.name[..]);
        let disambiguate: HashSet<_> = names_requiring_disambiguation(names).collect();

        // Add all nodes to the graph.
        // Keep track of "<name> <source>" to node-index mappings for the edge collection pass.
        let mut pkg_to_node: HashMap<String, pkg::NodeIx> = HashMap::new();
        for pkg in &self.package {
            // Note: `key` may be either `<name> <source>` or just `<name>` if disambiguation not
            // required.
            let key = pkg.name_disambiguated(&disambiguate).into_owned();
            let name = pkg.name.clone();
            let source: source::Pinned = pkg.source.parse().map_err(|e| {
                anyhow!("invalid 'source' entry for package {} lock: {:?}", name, e)
            })?;
            let pkg = pkg::Pinned { name, source };
            let node = graph.add_node(pkg);
            pkg_to_node.insert(key, node);
        }

        // On the second pass, add all edges.
        for pkg in &self.package {
            let key = pkg.name_disambiguated(&disambiguate);
            let node = pkg_to_node[&key[..]];
            // If `pkg.contract_dependencies` is None, we will be collecting an empty list of
            // contract_deps so that we will omit them during edge adding phase
            let contract_deps = pkg
                .contract_dependencies
                .as_ref()
                .into_iter()
                .flatten()
                .map(|contract_dep| (contract_dep, UnparsedDepKind::Contract));

View on GitHub (pinned to 47e5e902fa)

Solutions

  1. Delete Forc.lock and run forc build to re-resolve and regenerate it from Forc.toml - the lock is a derived artifact, never worth hand-fixing.
  2. If the lock must be hand-maintained, correct the entry to a valid pinned form such as git+https://github.com/FuelLabs/sway?tag=v0.49.0#<40-hex-commit>.
  3. Pin one forc version across the team and CI so lock format stays consistent.

Example fix

# before (Forc.lock)
[[package]]
name = "std"
source = "github.com/FuelLabs/sway" # malformed

# after
[[package]]
name = "std"
source = "git+https://github.com/FuelLabs/sway?tag=v0.49.0#8b4f3dd2c6db4a1d1c0d3e0b1f0ad79d1cd4c6e4"
Defensive patterns

Strategy: fallback

Validate before calling

// Rust, validate source entries before Lock::to_graph by round-tripping:
// let pinned: Result<source::Pinned, _> = pkg.source.parse();
// surface the first failing package name instead of a graph-wide error.

Try / catch

// On this error, the lock is unrecoverable-by-parsing: fall back to regeneration.
match lock.to_graph() {
    Ok(g) => { /* ... */ }
    Err(e) => { let _ = fs::remove_file("Forc.lock"); /* re-run dependency fetch */ }
}

Prevention

When it happens

Trigger: A Forc.lock whose [[package]] source entries are malformed: hand-edited strings, leftover merge-conflict markers, or a lock written by a different forc version whose source grammar differs from the reader's.

Common situations: Hand-resolved git merges of Forc.lock; upgrading/downgrading forc while keeping the old lock; scripts that rewrite locks; team members on mismatched toolchain versions.

Related errors


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