Skip to content

embedder: NeedsJspi refusal abandons an adapted Promise and leaks an unhandled rejection #328

Description

@lannbot

Summary

When a sync import returns a Promise that the runtime refuses with NeedsJspi, the runtime abandons its adapted Promise without a rejection handler. Catching the export refusal does not prevent a later unhandled Trap rejection.

Priority: medium. Reproduced with real Wasm on fd4266b516632e80943456a45aa64b95ea42f36f, Deno 2.9.5 / V8 15.0, Linux aarch64.

Reproduction

Instantiate the committed runtime/tests/embedder/host-result.wasm fixture using the normal translator/artifact helper, with this provider:

{
  "host:api/fallible": {
    check: () => Promise.reject(new Error("late host failure")),
  },
}

The sync import is deliberately unmarked. Call and catch await instance.exports.run(), then allow an event-loop turn.

Observed:

entry refused NeedsJspi
Uncaught (in promise) Trap: import 'host:api/fallible/check' threw Error: late host failure ...

Deno terminates the test module due to the uncaught rejection, despite the application catching the entry refusal.

Cause and authority

  • instantiate.ts:782–790 constructs an adapted Promise whose rejection becomes a Trap.
  • boundary.ts:1790–1806 rejects the capability request without observing the adapted Promise.
  • contracts/embedder-api.md:206–215 specifies a call-site refusal for unsupported Promise returns. Although the invalid import signature is a host error, the runtime must handle the intermediate Promise it created when refusing it.

The existing refusal test using a branded ComponentException misses this: adaptation turns that rejection into a fulfilled err value.

Acceptance criteria

  • Observe rejected adapted Promises on capability-refusal paths while preserving the specified call-site error.
  • Cover an unbranded rejected Promise after catching NeedsJspi, plus marked imports with jspi:false.
  • Check late fulfillment with ownership-bearing values so draining does not introduce abandoned conversion effects.
  • No unhandled rejection or test-module termination; run just gates for the repair.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingp0Known crash or major correctness bug

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions