FuelLabs/sway · error
`LoadDataId` refers to a non-existent data section entry
Error message
`LoadDataId` refers to a non-existent data section entry
What it means
During conversion of the allocated abstract instruction set into a final program, the compiler counts non-copy LoadDataId ops (loads whose target is not a small copy-type value) to reserve a pointer slot for each one. Counting requires has_copy_type(data_id), which returns None when the data id does not exist in the data section. The panic fires because a LoadDataId references a DataId that was never inserted into (or was removed from) the data section — an internal invariant violation of the lowering passes.
Source
Thrown at sway-core/src/asm_generation/fuel/programs/allocated.rs:61
//
// We reserve one data section pointer slot for each non-copy `LoadDataId`.
// The slots are filled in-place during the bytecode generation,
// which does not change the layout.
//
// We freeze the worst-case offset of the configurables region, pessimistically
// assuming that every far jump whose realization can insert a target word
// into the data section does insert one. `AddrDataId`s pointing to
// configurables are sized against this worst-case offset. Note that in practice
// this "pessimization" almost never results in generating two instructions
// `MOVI` + `ADD` instead of one `ADDI`.
let num_non_copy_loads = abstract_ops
.ops
.iter()
.filter(|op| match &op.opcode {
Either::Left(AllocatedInstruction::LoadDataId(_, data_id)) => !self
.data_section
.has_copy_type(data_id)
.expect("`LoadDataId` refers to a non-existent data section entry"),
_ => false,
})
.count();
self.data_section.reserve_pointer_slots(num_non_copy_loads);
let (far_jump_sizes, worst_case_far_jump_words) = abstract_ops.collect_far_jumps();
self.data_section
.freeze_configurables_base_offset(8 * worst_case_far_jump_words);
let (realized_ops, mut label_offsets) =
abstract_ops.lower_to_realized_ops(&mut self.data_section, &far_jump_sizes)?;
let ops = realized_ops.lower_to_allocated_ops();
// Collect the entry point offsets.
let entries = self
.entries
.into_iter()
.map(|(selector, label, name, test_decl_ref)| {View on GitHub (pinned to dad95cc42b)
Solutions
- Verify every LoadDataId emitted during abstract IR lowering is accompanied by inserting the corresponding entry into the data section
- Check that data section deduplication/pruning passes do not remove entries still referenced by emitted LoadDataId ops
- Reproduce with the failing contract and trace the DataId index/region back to where the load op was created
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at sway-core/src/asm_generation/fuel/programs/allocated.rs:61 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of FuelLabs/sway@dad95cc42b (2026-09-04).
Data as JSON: /api/errors/e7a85ef969911950.
Report an issue: GitHub.