Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Worklets without captured variables are rejected as "Regular javascript function" when transpiled by react-native-worklets' Babel plugin

Đang mở
#275 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

@wn-na đang làm issue này rồi.

Từ ngày 19/10/2026.

  • #276 của @wn-na — đang mở

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
55/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
cpp, javascript, react-native
Lĩnh vực
backend, mobile

Hướng nghiên cứu

Start with cpp/WKTJsiWorklet.h, especially isDecoratedAsWorklet() and createWorklet(), then trace how JsiObjectWrapper::setFunctionValue() handles a function without __closure. Reproduce with the supplied Babel output: a numeric __workletHash, string __initData.code, and no closure. Done when that no-capture worklet is recognized and invoked successfully while existing captured worklets still work.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Description

When a project uses the Babel plugin from react-native-worklets (the Reanimated 4 worklets package) together with react-native-worklets-core, any 'worklet' function that does not capture any outer variables is not recognized as a worklet by worklets-core.

Calling such a function from inside another worklet that runs on a worklets-core context throws:

Regular javascript function 't' cannot be shared. Try decorating the function with the 'worklet' keyword to allow the javascript function to be used as a worklet.

('t' is just the minified function name in a release bundle.)

We hit this through react-native-filament: EntitySelector's MaterialModifier worklet calls the module-level applyMaterialParameters worklet, which captures nothing, so every model with materialParameters fails on the worklet thread.

Environment

  • react-native: 0.88.0 (New Architecture, Hermes)
  • react-native-worklets-core: 1.6.3
  • react-native-worklets: 0.13.0 (its Babel plugin is active)
  • react-native-filament: 1.9.0 (where we first saw it; 1.11.0 has the same code)
  • Babel plugins:
    plugins: [
      ['react-native-worklets-core/plugin', { processNestedWorklets: true }],
      'react-native-worklets/plugin',
    ]
    

Minimal reproduction

import { Worklets } from 'react-native-worklets-core'

// Captures nothing from the outer scope
const double = (x: number) => {
  'worklet'
  return x * 2
}

const context = Worklets.createContext('repro')

// The worklet passed to runAsync captures `double`
context
  .runAsync(() => {
    'worklet'
    return double(21) // <- throws "Regular javascript function '...' cannot be shared"
  })
  .then(console.log)

If double captures any outer variable (so it gets a __closure), the call works.

What the transpiled code looks like

With the react-native-worklets plugin (0.13.0, and the same in the 0.14 nightlies), a worklet that captures nothing is emitted without __closure, and the hash is a number literal:

var double = function double_Factory([_worklet_123_init_data]) {
  const double = function (x) { return x * 2 }
  double.__workletHash = 123                    // number, not string
  double.__initData = _worklet_123_init_data   // { code: "(function ...)" }
  return double                                // no __closure assignment
}([_worklet_123_init_data])

The plugin only emits __closure when closureVariables.length > 0 (see plugin/index.js), so leaving it out is intended behavior there, not a bug.

Root cause

In cpp/WKTJsiWorklet.h:

  1. isDecoratedAsWorklet() returns true right away only when __workletHash is a string. Otherwise it requires __closure to be present, so a numeric hash with no __closure is treated as a regular function.
  2. createWorklet() returns early when __closure is undefined/null, so even if detection passed, the worklet would not be created.

JsiObjectWrapper::setFunctionValue() then wraps the function in a host function that throws the "cannot be shared" error when called.

Suggested fix

Treat a function as a worklet when __workletHash is a number and __initData.code is a string, and use an empty closure when __closure is missing. Code generated for a worklet with no captures never reads this.__closure, so an empty array is safe.

I have a small patch for this and can open a PR.

Possibly related

#258 reports release builds failing with "is not a Worklet" when the Reanimated plugin and the worklets-core plugin are used together. It might be the same root cause, but I haven't verified that.

Ngôn ngữ chính
C++
Star
791
Fork
66
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của margelo/react-native-worklets-core

Tất cả issue của margelo/react-native-worklets-core

Issue tương tự

Thêm issue về C++

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.