Skip to content

Empty finally block causes function to return undefined when try block contains a conditional return #5369

@hpp2334

Description

@hpp2334

Describe the bug

(The bug report was written by GLM 5.1 with opencode)

When a function contains a try/catch/finally with an empty finally block, and the try block contains an if statement with a return that is not taken, control flow is lost after the finally block. The function returns undefined instead of continuing to subsequent statements.

To Reproduce

This JavaScript code reproduces the issue:

function f(x) {
  try {
    if (x) return -1;
  } catch (e) {}
  return 42;
}
f(0); // → 42 ✓ (correct)

Adding an empty finally {} breaks it:

function g(x) {
  try {
    if (x) return -1;
  } catch (e) {} finally {}
  return 42;
}
g(0); // → undefined ✗ (should be 42)

The only difference is the addition of finally {}. The if (x) condition is false (since 0 is falsy), so the return -1 inside the try block is never executed. Control should fall through the empty finally and reach return 42, but instead the function returns undefined.

Expected behavior

Both functions should return 42. The empty finally {} block should be a no-op, and control flow should continue to return 42.

Build environment

  • OS: macOS
  • Version: 15.7.3
  • Target triple: x86_64-apple-darwin
  • Rustc version: rustc 1.94.1 (e408947bf 2026-03-25)
  • Boa version: git revision 3ce87f0fa03c5c037fb667f7f21a4996abbbc714 (Note: this appears to be a regression. The bug does not reproduce on the released boa_engine version 0.21.1)

Additional context

This was discovered while running React 19's react-reconciler inside Boa. React's dispatchSetStateInternal function uses the exact pattern if (cond) try { ... } catch (e) {} finally {}, causing all React state updates to silently fail — the function returns undefined, and the code that schedules a re-render (after the finally) is never reached.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions