{"record":{"id":"f170995a9de91b47","repo":"FuelLabs/sway","slug":"configurables-section-offset-not-found","errorCode":null,"errorMessage":"Configurables section offset not found","messagePattern":"Configurables section offset not found","errorType":"console","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"forc-util/src/bytecode.rs","lineNumber":111,"sourceCode":"            }\n\n            // Continue hashing the remaining instructions up to the configurables section offset.\n            instructions\n                .take(\n                    configurables_offset / fuel_asm::Instruction::SIZE\n                        - CONFIGURABLES_OFFSET_PREAMBLE,\n                ) // Minus 6 because we already hashed the first six\n                .for_each(|(_, raw)| {\n                    hasher.update(raw);\n                });\n\n            let hash_result = hasher.finalize();\n            let bytecode_id = format!(\"{hash_result:x}\");\n            return Ok(bytecode_id);\n        }\n    }\n\n    Err(anyhow!(\"Configurables section offset not found\"))\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[test]\n    fn test_get_bytecode_id_happy() {\n        // These binary files were generated from `examples/configurable_constants` and `examples/counter`\n        // using `forc build` and `forc build --release` respectively.\n        let bytecode_id: String =\n            get_bytecode_id(\"tests/fixtures/bytecode/debug-counter.bin\").expect(\"bytecode id\");\n        assert_eq!(\n            bytecode_id,\n            \"e65aa988cae1041b64dc2d85e496eed0e8a1d8105133bd313c17645a1859d53b\".to_string()\n        );\n\n        let bytecode_id =","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/FuelLabs/sway/blob/47e5e902faa42baf652dd6a0c88cd23390c1a614/forc-util/src/bytecode.rs#L93-L129","documentation":"get_bytecode_id detects a configurables-bearing binary by checking that instructions 4 and 5 (CONFIGURABLES_OFFSET_INSTR_LO/HI) both decode to fuel_asm::InvalidOpcode — the sentinel half-words encoding the configurables section offset. If they are not both InvalidOpcode, the expected preamble marker is absent and the function errors. The repo's own regression test reproduces this with a .bin produced by an older compiler that did not embed the offset.","triggerScenarios":"Hashing bytecode compiled by an old sway/forc version that predates the configurables-offset preamble, or hand-modified/malformed bytecode where the sentinel was clobbered.","commonSituations":"Computing contract IDs for artifacts built before a forc upgrade, CI caches holding stale .bin files across toolchain bumps, or checking in binaries built by mismatched toolchain versions.","solutions":["Rebuild the bytecode with the current `forc build` so the preamble contains the offset sentinel, then recompute the ID","Clear build caches (out/, CI artifact caches) so old-compiler binaries are regenerated","If you must support legacy binaries, hash them with a tool version matching the one that produced them"],"exampleFix":"# before (bin built by old compiler)\nforc contract-id --bytecode-file cached_old_counter.bin\n\n# after\nforc build && forc contract-id --bytecode-file out/debug/counter.bin","handlingStrategy":"validation","validationCode":"// Pre-check that the preamble carries the configurables-offset sentinel\n// (instructions 4 and 5 must decode to InvalidOpcode), mirroring get_bytecode_id.\nfn has_configurables_offset(path: &Path) -> bool {\n    let mut it = match forc_util::bytecode::parse_bytecode_to_instructions(path) {\n        Ok(it) => it,\n        Err(_) => return false,\n    };\n    let instrs: Vec<_> = (&mut it).take(6).collect();\n    instrs.len() == 6\n        && matches!(instrs[4].0, Err(_))\n        && matches!(instrs[5].0, Err(_))\n}","typeGuard":null,"tryCatchPattern":"match get_bytecode_id(&path) {\n    Ok(id) => Ok(id),\n    Err(e) if e.to_string() == \"Configurables section offset not found\" => {\n        Err(anyhow::anyhow!(\"{} was built by an older compiler; rebuild with current forc\", path.display()))\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Regenerate .bin artifacts with the current forc after every toolchain upgrade before computing IDs","Don't cache build artifacts across toolchain versions in CI"],"tags":["forc-util","bytecode","version-mismatch","configurables"],"backgroundTag":null,"analyzedSha":"47e5e902faa42baf652dd6a0c88cd23390c1a614","analyzedAt":"2026-08-16T07:57:45.555Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}