FuelLabs/sway · error
hex salt declaration needs to start with 0x
Error message
hex salt declaration needs to start with 0x
What it means
HexSalt::from_str requires salt strings to begin with the literal prefix 0x, which is stripped before delegating the remainder to fuel_tx::Salt::from_str. This specific error covers only the missing-prefix case; a present-but-malformed body produces the follow-on error instead. It surfaces wherever salts are parsed from text: contract-dependency salt fields in Forc.toml and the forc add --salt path.
Source
Thrown at forc-pkg/src/manifest/mod.rs:269
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct Network {
#[serde(default = "default_url")]
pub url: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct HexSalt(pub fuel_tx::Salt);
impl FromStr for HexSalt {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
// cut 0x from start.
let normalized = s
.strip_prefix("0x")
.ok_or_else(|| anyhow::anyhow!("hex salt declaration needs to start with 0x"))?;
let salt: fuel_tx::Salt =
fuel_tx::Salt::from_str(normalized).map_err(|e| anyhow::anyhow!("{e}"))?;
let hex_salt = Self(salt);
Ok(hex_salt)
}
}
impl Display for HexSalt {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let salt = self.0;
write!(f, "{salt}")
}
}
fn default_hex_salt() -> HexSalt {
HexSalt(fuel_tx::Salt::default())
}
View on GitHub (pinned to 47e5e902fa)
Solutions
- Prefix the value with 0x: salt = "0x<64 hex>".
- Copy salts from Forc.lock, which always prints them 0x-prefixed via the Display impl directly below this code.
- When in doubt omit the salt and let the default zero salt apply.
Example fix
# before (Forc.toml)
[contract-dependencies]
auth = { git = "...", salt = "deadbeef0000..." }
# after
[contract-dependencies]
auth = { git = "...", salt = "0xdeadbeef000000000000000000000000000000000000000000000000000000" } Defensive patterns
Strategy: validation
Validate before calling
// Rust, enforce the 0x prefix before parsing a salt string:
fn has_0x_prefix(s: &str) -> bool { s.trim().starts_with("0x") } Try / catch
// anyhow Result from HexSalt::from_str; distinguish prefix vs body failure:
match HexSalt::from_str(s) {
Err(e) if e.to_string().contains("needs to start with 0x") =>
eprintln!("prefix the salt with 0x"),
Err(e) => eprintln!("salt body invalid: {e}"),
Ok(salt) => salt,
} Prevention
- Author every salt in manifests/CLI as 0x + 64 hex chars.
- Copy salts from generated Forc.lock files.
- If you dislike prefixes, omit the salt and accept the default.
When it happens
Trigger: A salt value without 0x - e.g. salt = "abcdef..." under [contract-dependencies] in Forc.toml, or --salt 0000... on the command line - being parsed into a HexSalt.
Common situations: Copying a bare-hex salt from a block explorer or another tool; hand-writing manifest entries modeled on other hex fields; scripts generating salts without the prefix.
Related errors
- {e}
- invalid salt in lock file: {e}
- failed to write toml file: {}
- Invalid salt format: {}
- the dependency `{}` could not be found in `{}`
AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16).
Data as JSON: /api/errors/2c710c8f233704e6.
Report an issue: GitHub.