FuelLabs/sway · error
{e}
Error message
{e} What it means
After stripping 0x, HexSalt::from_str delegates to fuel_tx::Salt::from_str, which demands exactly 64 hex characters (the 32-byte Salt type). This pass-through error fires for wrong-length or non-hex bodies - the message is the underlying fuel-tx error verbatim. It is the second of the two salt parse failures (the first being the missing-0x check one line above).
Source
Thrown at forc-pkg/src/manifest/mod.rs:271
#[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())
}
#[serde_as]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]View on GitHub (pinned to 47e5e902fa)
Solutions
- Use exactly 64 hex characters after 0x (32 bytes).
- For the zero salt write 0x followed by 64 zeros, or omit the salt to get the default.
- Verify programmatically: the string after 0x must have len 64 and contain only [0-9a-fA-F].
Example fix
# before salt = "0x1234" # after salt = "0x0000000000000000000000000000000000000000000000000000000000001234"
Defensive patterns
Strategy: validation
Validate before calling
// Rust, full salt-shape check before parsing:
fn valid_salt(s: &str) -> bool {
match s.strip_prefix("0x") {
Some(body) => body.len() == 64 && body.chars().all(|c| c.is_ascii_hexdigit()),
None => false,
}
} Type guard
// Type-guard style predicate usable as a gate:
fn is_complete_hex_salt(s: &str) -> bool {
let b = s.as_bytes();
b.len() == 66 && b[0]==b'0' && b[1]==b'x'
&& b[2..].iter().all(|c| c.is_ascii_hexdigit())
} Try / catch
// anyhow Result - surface the fuel-tx message (it names length/hex problems):
match HexSalt::from_str(salt_str) {
Ok(s) => s,
Err(e) => { eprintln!("invalid salt body: {e}; need 64 hex chars after 0x"); return; }
} Prevention
- Salt bodies are exactly 32 bytes: 64 hex characters after 0x.
- Generate salts programmatically (e.g. hex of a 32-byte hash) instead of hand-typing.
- Avoid editor line-wrapping inside salt string literals.
When it happens
Trigger: A salt like 0xdeadbeef (too short), 0x plus more/fewer than 64 hex chars, or containing non-hex characters (g-z, punctuation) inside a contract-dependency salt field or CLI --salt value.
Common situations: Short placeholder salts (0x0); copying truncated salts; mixed-in checksum characters that are not hex; line-wrapping in editors splitting the salt string.
Related errors
- hex salt declaration needs to start with 0x
- 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/39c680b1d16174bb.
Report an issue: GitHub.