FuelLabs/sway · error
failed to parse dependency "{}": {}
Error message
failed to parse dependency "{}": {} What it means
During Lock::to_graph, each package's dependency lines ('<name> <source>' or '(<name> <source>) <salt>') are parsed by parse_pkg_dep_line. A syntax error inside one line produces this message quoting the exact offending line, so the line itself tells you what is wrong. It signals lock-file corruption, not a missing package or network issue.
Source
Thrown at forc-pkg/src/lock.rs:220
// 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));
// If `pkg.dependencies` is None, we will be collecting an empty list of
// lib_deps so that we will omit them during edge adding phase
let lib_deps = pkg
.dependencies
.as_ref()
.into_iter()
.flatten()
.map(|lib_dep| (lib_dep, UnparsedDepKind::Library));
for (dep_line, dep_kind) in lib_deps.chain(contract_deps) {
let (dep_name, dep_key, dep_salt) = parse_pkg_dep_line(dep_line)
.map_err(|e| anyhow!("failed to parse dependency \"{}\": {}", dep_line, e))?;
let dep_node = pkg_to_node
.get(dep_key)
.copied()
.ok_or_else(|| anyhow!("found dep {} without node entry in graph", dep_key))?;
let dep_name = dep_name.unwrap_or(&graph[dep_node].name).to_string();
let dep_kind = match dep_kind {
UnparsedDepKind::Library => DepKind::Library,
UnparsedDepKind::Contract => {
let dep_salt = dep_salt.unwrap_or_default();
DepKind::Contract { salt: dep_salt }
}
};
let dep_edge = Edge::new(dep_name, dep_kind);
graph.update_edge(node, dep_node, dep_edge);
}
}
Ok(graph)View on GitHub (pinned to 47e5e902fa)
Solutions
- Delete Forc.lock and run forc build to regenerate every dependency line from Forc.toml.
- If editing is required, match the exact grammar: (name source) salt for contract deps with salt, name source otherwise.
- Adopt a repo convention to regenerate the lock after dependency changes instead of merging it.
Example fix
# before (Forc.lock) dependencies = [ "auth lib git+https://github.com/x/auth#<<<<<<< HEAD", # merge garbage ] # after - regenerate: rm Forc.lock && forc build
Defensive patterns
Strategy: fallback
Validate before calling
// Rust, pre-validate each dependency line before graph construction:
fn dep_lines_ok(lock: &Lock) -> bool {
lock.package.iter().all(|p| p.dependencies.as_ref()
.into_iter().flatten().all(|l| parse_pkg_dep_line(l).is_ok()))
} Try / catch
// Parse failure of a derived artifact -> regenerate:
match lock.to_graph() {
Ok(g) => { /* ... */ }
Err(_) => { fs::remove_file(lock_path).ok(); /* re-resolve from Forc.toml */ }
} Prevention
- Treat Forc.lock dependency lines as machine-written only.
- After merges touching Forc.lock, delete it and rebuild instead of merging content.
- Keep dependency declarations in Forc.toml as the single source of truth.
When it happens
Trigger: A dependency line under a package entry in Forc.lock that does not parse: missing source after the name, stray characters, half-deleted merge-conflict text, or a salt part that breaks the expected bracket layout before the salt itself is validated.
Common situations: Manual edits to Forc.lock; bad merge-conflict resolution; tools that reformat the lock file; mismatched forc versions writing subtly different line formats.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- missing closing parenthesis
- missing pkg string
- invalid salt in lock file: {e}
- failed to read {}: {}
- invalid 'source' entry for package {} lock: {:?}
AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16).
Data as JSON: /api/errors/7076978fd191d8a8.
Report an issue: GitHub.