Files
Dylan Conway cda1e97d69 fix(napi): allow structuredClone on napi_create_object results (#27444)
## What does this PR do?

Fixes #25658 — `structuredClone()` throwing `DataCloneError` on objects
created via `napi_create_object`, which works in Node.js.

## Root cause

Bun's `napi_create_object` creates a `NapiPrototype` (a
`JSDestructibleObject` subclass with an inline `napiRef` field for fast
`napi_wrap`/`napi_unwrap`), not a plain `JSFinalObject`.

WebKit's `SerializedScriptValue` serializer checks:
```cpp
if (inObject->classInfo() != JSFinalObject::info())
    return SerializationReturnCode::DataCloneError;
```

`NapiPrototype` has its own `ClassInfo`, so the check fails.

Node.js uses `v8::Object::New()` which creates a truly plain V8 object —
V8's serializer clones it fine.

## Fix

Add `NapiPrototype::info()` to the serializer's allowlist. The inline
`napiRef` C++ field is invisible to property enumeration (serializer
uses `getOwnPropertyNames` with `PrivateSymbolMode::Exclude`), so cloned
objects correctly contain only JS properties — matching Node.js, where
`napi_unwrap` on a clone also fails.

## How did you verify your code works?

- Added `test_napi_create_object_structured_clone` using
`checkSameOutput` which runs on both Node and Bun and asserts identical
output
- Verified test **fails** with `USE_SYSTEM_BUN=1` (throws
`DataCloneError`)
- Verified test **passes** with `bun bd test`
- Verified existing `test/js/web/workers/structured-clone.test.ts` still
passes (118 tests)
2026-03-01 02:03:36 -08:00
..