FAQ
Table Of Contents
- Warning:
new (std::nothrow) int[0]
Returnsnullptr
, Try Fixing It! - Some Extension Functions Are Unavailable in Auto-Binding Mode
- App Hangs When "Wait for Debugger" Option Is Checked
StaticClass
Returns UnexpectedUClass
in TypeScript-Generated Blueprints- macOS Error: "Cannot open libv8.dylib because the developer cannot be verified"
- "XXXProject could not be compiled" Error in Blueprint-Only Projects
- Runtime Errors About Missing Fields After Packaging
- Error in UE5: "Construct TypeScript Object TestActor_C_1(...) on illegal thread!"
- Avoiding "Access Invalid Object" Exceptions
- Garbage Collection (GC) Behavior
- UE Object Is Held by
Puerts_UserObjectRetainer
- Scripts Not Running After Packaging (Mobile/PC)
- TypeScript Version Upgrade
ue_bp.d.ts
Errors, Regeneration Doesn’t Help- TS Class Inheritance Doesn’t Generate Proxy Blueprints
- Syntax Errors in
ue_bp.d.ts
- Intermittent "Maximum Call Stack Size Exceeded" Error
Warning: new (std::nothrow) int[0]
Returns nullptr
, Try Fixing It!
Unreal Engine overrides the new
operator in a way that doesn't comply with the C++ standard: when using std::nothrow
to allocate an array of length 0, it returns nullptr
. According to the standard, it should return a valid pointer and only return nullptr
on out-of-memory (OOM). This behavior misleads standard-compliant runtimes like V8 into thinking an OOM occurred, which causes an abort.
This issue is confirmed by Epic and currently only observed on Windows.
Puerts will detect this issue and patch the memory allocation behavior. When it does, it logs the warning:
“new (std::nothrow) int[0] return nullptr, try fix it!”
This is just an informational warning and does not impact functionality.
Some Extension Functions Are Unavailable in Auto-Binding Mode
This happens because the Puerts module initializes early and cannot discover extension functions defined in modules that load afterward.
Solution:
After all modules are initialized, call the following API to re-scan for extension methods:
IPuertsModule::Get().InitExtensionMethodsMap();
App Hangs When "Wait for Debugger" Option Is Checked
This option deliberately pauses the process to wait for a debugger to attach. Once a debugger connects, execution continues.
If you enabled it by accident and haven't configured a debugger, you can terminate the process and set the value to False
in the following config file:
Config/DefaultPuerts.ini
StaticClass
Returns Unexpected UClass
in TypeScript-Generated Blueprints
TypeScript classes do not have a StaticClass()
method. When called, it returns the first class in the inheritance chain that does have this method, along with its UClass
.
This can cause confusion—like missing subclass methods or CreateDefaultSubobject
errors stating the class is abstract.
Correct Usage:
Use the following to load a blueprint:
UE.Class.Load("path/to/your/blueprint/file")
macOS Error: "Cannot open libv8.dylib because the developer cannot be verified"
Navigate to the directory containing the .dylib
file (usually under:
YourProject/Plugins/Puerts/ThirdParty/v8/Lib/macOSdylib
) and run:
sudo xattr -r -d com.apple.quarantine *.dylib
"XXXProject could not be compiled" Error in Blueprint-Only Projects
In Blueprint-only projects, Unreal Engine doesn't compile C++ plugins automatically. You need to manually generate a Visual Studio (or Xcode on macOS) project and compile from the IDE.
Runtime Errors About Missing Fields After Packaging
This is usually due to inconsistent handling of FName
between the editor and runtime—FName
is case-sensitive in the editor but case-insensitive at runtime.
For example, if you defined a field count
in Blueprints and generated code in the editor, it works fine. But after packaging, if somewhere a Count
field is initialized first, it gets reused due to how FName.ToString()
works.
So your script accessing count
will fail because the actual field is Count
.
Error in UE5: "Construct TypeScript Object TestActor_C_1(...) on illegal thread!"
This is caused by UE5 enabling AsyncLoadingThreadEnabled
by default.
Solution: Disable this setting to avoid the issue.
Avoiding "Access Invalid Object" Exceptions
This exception is thrown by Puerts when it detects calls on an invalidated object. Any such call (including UObject::IsValid
) will raise the exception.
Though technically easy to add a check API, doing so would clutter business logic. Instead:
- Design your logic to avoid holding onto invalid objects (e.g., clean up on scene transitions).
- If unavoidable and non-critical, use try-catch to suppress the exception.
Garbage Collection (GC) Behavior
When a UE object is passed to TypeScript, Puerts creates a stub object that proxies native calls. There are two GC ownership models:
1. Stub Owns UE Object (managed by JS GC)
- If JS GC collects the stub, it drops its reference to the UE object.
- If UE has no other references to the object, UE GC will collect it.
2. UE Owns Stub (managed by UE GC)
- If UE GC collects the UE object, it also drops the stub reference.
- If JS has no remaining references to the stub, JS GC will collect it.
Scenarios where UE owns stub:
- TS class inherits a UE class
- Using
mixin
withobjectTakeByNative
- Using deprecated
makeUClass
In other cases, the stub usually owns the UE object and keeps it alive from the JS side.
Important:
Even if an object is still referenced, UE can still forcibly destroy it (e.g., during scene transitions). This differs from garbage collectors in C#, Java, Lua, etc.
UE Object Is Held by Puerts_UserObjectRetainer
This indicates that the JS-side proxy object hasn't been released yet.
GC requires:
- No references to the object.
- The object is found during GC and released.
For V8:
- It uses generational GC, so old generation scans aren't frequent.
- To speed up collection, use:
FJsEnv::LowMemoryNotification(); // Hint V8 to GC
FJsEnv::RequestFullGarbageCollectionForTesting(); // Force full GC (slow)
Scripts Not Running After Packaging (Mobile/PC)
Since JavaScript files aren't UE assets (*.asset
), they must be manually included in packaging.
Fix:
Go to Project Settings → Packaging → Additional Non-Asset Directories to Package, and add the Content/JavaScript
directory.
TypeScript Version Upgrade
If UE class inheritance is enabled, Puerts uses the TypeScript compiler.
Installed under:
YourProject/Plugins/Puerts/Content/JavaScript/PuertsEditor
(and copied to YourProject/Content/JavaScript/PuertsEditor
)
To upgrade:
- Modify
package.json
in both locations. - Run
npm install .
in those directories.
Version Compatibility:
- Long-term stable:
3.4.5
,4.4.4
,4.7.4
- Tested and works:
4.8.2
- Not supported:
>4.8.3
If UE class inheritance is not enabled, these version restrictions don't apply.
ue_bp.d.ts
Errors, Regeneration Doesn’t Help
Blueprint declaration files are generated incrementally. If dependencies change or the file is altered by version control, try full regeneration:
Puerts.Gen FULL
TS Class Inheritance Doesn’t Generate Proxy Blueprints
Troubleshooting:
In UE Command Line, run:
puerts ls
If it returns
Puerts command not initialized
, your setup might be incorrect. Check the installation steps.To find a specific TS class:
puerts ls TsTestActor
- If it doesn't show, it’s not in the TS project. Check
tsconfig.json
.
- If it doesn't show, it’s not in the TS project. Check
If found, check
isBP
andprocessed
columns:- If
isBP = false
andprocessed = true
, format is incorrect. Refer to Puerts’ "Inheriting Engine Classes" documentation.
- If
You can manually trigger compilation with:
puerts compile <file-id>
Replace
<file-id>
with the ID frompuerts ls
.
Syntax Errors in ue_bp.d.ts
This usually comes from illegal characters (unsupported by TS) in Blueprint paths, field names, or parameters.
Solutions:
- If only a few Blueprints are affected, blacklist them in Project Settings → Puerts.
- For many invalid Blueprints, place valid ones in a separate directory and generate types for that path:
Puerts.Gen PATH=/Game/StarterContent
Intermittent "Maximum Call Stack Size Exceeded" Error
If this happens occasionally (not always), it’s likely due to multi-threaded access to FJsEnv
.
Solution:
Add THREAD_SAFE
macro to JsEnv.Build.cs
.
Note:
- On V8 backend, this resolves multi-threading issues.
- On QJS backend, multi-threading is not supported and may throw obscure
<unknown>:-1
errors. - If the error is consistent, you likely have a recursive loop in your JS code.