windmill-labs/windmill · error
hex string did not decode to an u64: {s}
Error message
hex string did not decode to an u64: {s} What it means
to_i64 decodes a hex string expected to encode a 64-bit big-endian integer. If hex::decode succeeds but yields fewer than 8 bytes, the string cannot represent a u64 and this error is returned (note the message says u64 although the function returns i64).
Source
Thrown at backend/windmill-types/src/scripts.rs:738
let languages: Vec<ScriptLang> = s
.split(",")
.map(ScriptLang::from_str)
.try_collect()
.map_err(|e: anyhow::Error| serde::de::Error::custom(e.to_string()))?;
let languages = if languages.is_empty() {
None
} else {
Some(languages)
};
Ok(languages)
}
pub fn to_i64(s: &str) -> anyhow::Result<i64> {
let v = hex::decode(s)?;
if v.len() < 8 {
return Err(anyhow::anyhow!("hex string did not decode to an u64: {s}",));
}
let nb: u64 = u64::from_be_bytes(
v[0..8]
.try_into()
.map_err(|_| hex::FromHexError::InvalidStringLength)?,
);
Ok(nb as i64)
}
pub fn to_hex_string(i: &i64) -> String {
hex::encode(i.to_be_bytes())
}
#[derive(Deserialize, Serialize)]
pub struct HubScript {
pub content: String,
pub lockfile: Option<String>,
pub language: ScriptLang,View on GitHub (pinned to e474e8803c)
Solutions
- Ensure the hex string encodes a full 8-byte value (16 hex characters)
- Regenerate the value at the source instead of truncating it
- Verify hex::decode succeeded (invalid chars would fail earlier with a hex error)
- Also confirm the string has no `0x` prefix, which decode rejects
Example fix
// before
let n = windmill::to_i64("abcd")?; // 2 bytes
// after
let n = windmill::to_i64("000000000000abcd")?; // 8 bytes Defensive patterns
Strategy: validation
Validate before calling
def ensure_u64_hex(s: str) -> str:
body = s[2:] if s.startswith("0x") else s
if len(body) != 16 or any(c not in "0123456789abcdefABCDEF" for c in body):
raise ValueError(f"expected 16 hex chars encoding a u64, got {s!r}")
return body.lower() Try / catch
match windmill_types::scripts::to_i64(s) {
Err(e) if e.to_string().contains("hex string did not decode") => {
eprintln!("value {s} is not a full 8-byte hex encoding");
}
other => other?,
} Prevention
- Never truncate encoded integer hex strings
- Zero-pad to 16 hex chars when serializing
- Strip 0x prefixes before decoding
- Add a round-trip encode/decode test for persisted values
When it happens
Trigger: Passing a hex string shorter than 16 hex chars (fewer than 8 bytes) to to_i64 — e.g. a truncated hash prefix or a malformed encoded integer.
Common situations: Storing/truncating encoded values in the database; hand-constructed hex ids; mismatched encoding between writer and reader.
Related errors
- Could not parse embedded manifest: {}
- YAML emit error: {}
- Failed to parse Cargo.toml.default
- no policy could be derived for runnable(s) ${malformed.join(
- File ${path} is encoded as UTF-32 LE, which is not supported
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/dd714e336d995592.
Report an issue: GitHub.