FuelLabs/sway · error
Invalid salt format: {}
Error message
Invalid salt format: {} What it means
When forc add inserts a contract dependency into Forc.toml's [contract-dependencies], the optional salt is converted via HexSalt::from_str; failure is wrapped as 'Invalid salt format'. The underlying causes are exactly the two wrapped errors from manifest/mod.rs: a salt not starting with 0x, or a 0x-prefixed body that is not exactly 64 hex characters (32 bytes).
Source
Thrown at forc-pkg/src/manifest/dep_modifier.rs:323
doc[§ion_name] = Item::Table(Table::new());
}
let table = doc[section_name.as_str()].as_table_mut().unwrap();
match self {
Section::Deps => {
let item = match dep_data {
Dependency::Simple(ver) => ver.to_string().into(),
Dependency::Detailed(details) => {
Item::Value(toml_edit::Value::InlineTable(generate_table(&details)))
}
};
table.insert(&dep_name, item);
}
Section::ContractDeps => {
let resolved_salt = match salt.as_ref().or(salt.as_ref()) {
Some(s) => {
HexSalt::from_str(s).map_err(|e| anyhow!("Invalid salt format: {}", e))?
}
None => HexSalt(fuel_tx::Salt::default()),
};
let contract_dep = ContractDependency {
dependency: dep_data,
salt: resolved_salt.clone(),
};
let dep = &contract_dep.dependency;
let salt: &HexSalt = &contract_dep.salt;
let item = match dep {
Dependency::Simple(ver) => {
let mut inline = InlineTable::default();
inline.insert("version", Value::from(ver.to_string()));
inline.insert("salt", Value::from(format!("0x{salt}")));
Item::Value(toml_edit::Value::InlineTable(inline))
}
Dependency::Detailed(details) => {View on GitHub (pinned to 47e5e902fa)
Solutions
- Format the salt as 0x + 64 hex chars, e.g. 0x0000000000000000000000000000000000000000000000000000000000000000 for the default.
- Omit --salt entirely to get the default zero salt (HexSalt(fuel_tx::Salt::default()) in the source).
- Strip surrounding quotes/whitespace the shell may have preserved in the value.
Example fix
# before $ forc add --contract-dependency mydep --salt deadbeef # after $ forc add --contract-dependency mydep --salt 0x00000000000000000000000000000000deadbeef000000000000000000000000
Defensive patterns
Strategy: validation
Validate before calling
// Rust, pre-check a --salt value before the DepModifier runs:
fn valid_hex_salt(s: &str) -> bool {
let body = s.strip_prefix("0x").unwrap_or("");
body.len() == 64 && body.chars().all(|c| c.is_ascii_hexdigit())
} Try / catch
// anyhow Result from the dep-modifier flow; catch and restate format:
match add_contract_dep(...) {
Err(e) if e.to_string().contains("Invalid salt format") =>
eprintln!("salt must be 0x + 64 hex chars, or omitted"),
other => other.unwrap(),
} Prevention
- Always format salts as 0x followed by 64 hex characters.
- Omit --salt for the default zero salt.
- Copy salts from Forc.lock output, which is already correctly formatted.
When it happens
Trigger: forc add --contract-dependency dep --salt <value> (or the programmatic equivalent calling the DepModifier insert API) where value is not 0x followed by 64 hex characters.
Common situations: Passing an EVM-style salt with different length; copying a salt with whitespace/quotes from a terminal; forgetting the 0x prefix; using a short placeholder like 0x0.
Related errors
- invalid salt in lock file: {e}
- missing dependency name
- invalid version requirement `{v}`
- the dependency `{}` could not be found in `{}`
- hex salt declaration needs to start with 0x
AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16).
Data as JSON: /api/errors/42b50e30214b7775.
Report an issue: GitHub.