FuelLabs/sway · error · anyhow::Error
Incomplete bytecode
Error message
Incomplete bytecode
What it means
get_bytecode_id requires at least CONFIGURABLES_OFFSET_PREAMBLE = 6 instructions (48 bytes; indices 0..5, with the offset sentinel at indices 4 and 5) in the bytecode file because the Fuel VM preamble embeds the configurables section offset there. If the instruction iterator runs dry before six entries are collected, the file is truncated/empty/not real bytecode and this error returns.
Source
Thrown at forc-util/src/bytecode.rs:74
Ok(InstructionWithBytesIterator::new(buf_reader))
}
/// Gets the bytecode ID from a bytecode file. The bytecode ID is the hash of the bytecode after removing the
/// condigurables section, if any.
pub fn get_bytecode_id<P>(path: P) -> anyhow::Result<String>
where
P: AsRef<Path> + Clone,
{
let mut instructions = parse_bytecode_to_instructions(path.clone())?;
// Collect the first six instructions into a temporary vector
let mut first_six_instructions = Vec::with_capacity(CONFIGURABLES_OFFSET_PREAMBLE);
for _ in 0..CONFIGURABLES_OFFSET_PREAMBLE {
if let Some(instruction) = instructions.next() {
first_six_instructions.push(instruction);
} else {
return Err(anyhow!("Incomplete bytecode"));
}
}
let (lo_instr, low_raw) = &first_six_instructions[CONFIGURABLES_OFFSET_INSTR_LO];
let (hi_instr, hi_raw) = &first_six_instructions[CONFIGURABLES_OFFSET_INSTR_HI];
if let Err(fuel_asm::InvalidOpcode) = lo_instr {
if let Err(fuel_asm::InvalidOpcode) = hi_instr {
// Now assemble the configurables offset.
let configurables_offset = usize::from_be_bytes([
low_raw[0], low_raw[1], low_raw[2], low_raw[3], hi_raw[0], hi_raw[1], hi_raw[2],
hi_raw[3],
]);
// Hash the first six instructions
let mut hasher = Sha256::new();
for (_, raw) in first_six_instructions {
hasher.update(raw);View on GitHub (pinned to 47e5e902fa)
Solutions
- Rebuild with `forc build` and use the newly produced .bin
- Confirm the file is the raw bytecode binary (out/debug/<pkg>.bin), not the ABI json, and is at least 48 bytes
- If it persists, delete the out/ directory entirely and rebuild from scratch
Example fix
# before forc contract-id --bytecode-file out/debug/my_pkg-abi.json # after forc contract-id --bytecode-file out/debug/my_pkg.bin
Defensive patterns
Strategy: validation
Validate before calling
const MIN_INSTR_BYTES: u64 = 6 * 4; // CONFIGURABLES_OFFSET_PREAMBLE instructions, 4 bytes each
let meta = std::fs::metadata(&bin_path)?;
if meta.len() < MIN_INSTR_BYTES {
anyhow::bail!("bytecode too small ({} bytes); rebuild with `forc build`", meta.len());
} Try / catch
let id = match get_bytecode_id(&path) {
Ok(id) => id,
Err(e) if e.to_string() == "Incomplete bytecode" => {
anyhow::bail!("artifact at {} is empty/truncated — rerun `forc build`", path.display())
}
Err(e) => return Err(e),
}; Prevention
- Never feed ABI json or placeholder files into --bytecode-file; verify the artifact is the raw .bin
- Treat interrupted builds as producing no artifacts: check exit status before using out/ files
When it happens
Trigger: Passing an empty or truncated .bin, a non-bytecode file (e.g. a .json ABI file) to get_bytecode_id / `forc contract-id --bytecode-file`, or a build artifact cut short by a full disk or interrupted `forc build`.
Common situations: Confusing the ABI json artifact with the binary artifact in out/debug, partial artifacts left after a cancelled build, or a script globbing *.bin in a directory that contains placeholder files.
Related errors
- {}: file not found
- Configurables section offset not found
- Serialized receipts does not contain {} th index
- only Fuel VM is supported for log decoding
- log id is missing
AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16).
Data as JSON: /api/errors/75ff9613b1f74cde.
Report an issue: GitHub.