BoundaryML/baml · critical

missing trap PC for dead-unreachable jump target

Error message

missing trap PC for dead-unreachable jump target

What it means

Panic in resolve_pending_target_pc for PendingJumpTarget::Trap when self.trap_pc is None. The emitter tracks the PC of an emitted trap (unreachable/dead-code) instruction so jumps to dead targets can be redirected there; if no trap was ever emitted, the dead-unreachable jump has nowhere to point. This signals an emitter invariant break: a jump was recorded as dead-target but no trap landing pad exists.

Source

Thrown at baml_language/crates/baml_compiler2_emit/src/emit.rs:2738

                };
                target = target.wrapping_add_signed(next_offset);
            }
            self.patch_jump_to(source, target);
        }
    }

    /// Resolve a pending jump target to a concrete bytecode PC.
    fn resolve_pending_target_pc(&self, target: PendingJumpTarget) -> usize {
        match target {
            PendingJumpTarget::Block(target_block) => {
                *self.block_addresses.get(&target_block).unwrap_or_else(|| {
                    panic!(
                        "missing block address for jump target {target_block:?}; target may have been skipped without redirect resolution"
                    )
                })
            }
            PendingJumpTarget::Trap => self.trap_pc.unwrap_or_else(|| {
                panic!("missing trap PC for dead-unreachable jump target")
            }),
        }
    }

    /// Patch a specific jump to a specific destination.
    #[allow(clippy::cast_possible_wrap)]
    fn patch_jump_to(&mut self, instruction_idx: usize, destination: usize) {
        let offset = destination as isize - instruction_idx as isize;
        match self.bytecode.instructions[instruction_idx] {
            Instruction::Jump(_) => {
                self.bytecode.instructions[instruction_idx] = Instruction::Jump(offset);
            }
            Instruction::PopJumpIfFalse(_) => {
                self.bytecode.instructions[instruction_idx] = Instruction::PopJumpIfFalse(offset);
            }
            Instruction::JumpIfFalse(_) => {
                self.bytecode.instructions[instruction_idx] = Instruction::JumpIfFalse(offset);
            }

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Ensure a trap instruction is always emitted (and trap_pc recorded) whenever any jump target is marked Trap.
  2. Redirect dead-unreachable jumps to any valid address (e.g. end of function) instead of the trap PC when no trap exists.
  3. Capture the failing BAML input and report it as a compiler bug.
  4. Downgrade to a version of baml-cli that does not exhibit the mis-emission.
Defensive patterns

Strategy: fallback

Try / catch

// compiler panic — not user-catchable; wrap the build step
if !baml_cli_build_succeeds() {
    pin_previous_compiler_version();
}

Prevention

When it happens

Trigger: Patching a PendingJumpTarget::Trap in a function where no trap instruction was emitted — typically when the emitter skipped emitting the trap for an unreachable region but still recorded a trap-targeted jump.

Common situations: Seen during compiler development when changing dead-code emission or throw handling so that a `throw` in unreachable code no longer emits a trap while jumps still reference it.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/d5db1cd3b9810c4d. Report an issue: GitHub.