isolated-vm icon indicating copy to clipboard operation
isolated-vm copied to clipboard

Execution returns `Reference {}` instead of actual result values

Open DtonGamer opened this issue 1 month ago • 2 comments

I'm using isolated-vm to create a secure execution environment for user-provided code. When executing code within an isolate, the result is not properly accessible from the main context. Instead of returning the actual result value, I'm getting a Reference {} object.

Code Example:

1 const ivm = require('isolated-vm');
2 
3 async function test() {
4   const isolate = new ivm.Isolate({ memoryLimit: 128 });
5   const context = await isolate.createContext();        
6 
7   const jail = context.global;
8   await jail.set('global', jail.derefInto());
9   await jail.set('_result', null);

10 11 const code = ` 12 (function() {

13 const $input = _input; 14 let items = []; 15 if (Array.isArray($input)) { 16 items = $input.map(data => ({ json: data }));
17 } else { 18 items = [{ json: $input }]; 19 } 20
21 // User code that should assign to result 22 result = { processed: true, data: items };
23
24 // Set the final result 25 if (typeof result !== 'undefined') { 26 _result = { result: result, logs: [] }; 27 } else { 28 _result = { result: items, logs: [] }; 29 } 30 })(); 31 `; 32 33 const inputData = { userId: "test-user" }; 34 await jail.set('_input', new ivm.ExternalCopy(inputData).copyInto()); 35 36 await context.eval(code); 37
38 // This returns a Reference {} instead of the actual value 39 const result = await context.global.get('_result'); 40 console.log('Result type:', typeof result, result); // Shows: Result type: object [Reference {}] 41
42 // This should work to get the actual value but returns {} for some reason 43 const actualResult = await result.copy(); 44 console.log('Actual result:', actualResult); // Shows: Actual result: {} 45 } 46 47 test();

Expected Behavior: When calling context.global.get('_result') followed by .copy(), I expect to get the actual object that was assigned to _result within the isolate context (e.g., { result: { processed: true, data: [ /* ... */ ] }, logs: [] }).

Actual Behavior:

  • context.global.get('_result') returns a Reference {} object
  • result.copy() returns an empty object {} instead of the expected result

Environment:

  • Node.js: v20.x
  • isolated-vm: 6.0.2
  • OS: Windows 10/11

What I've tried:

  1. Using result.copy() as suggested in documentation
  2. Different execution contexts
  3. Various approaches to setting and getting the result variable

Questions:

  1. Am I using the correct approach to extract values from the isolate context?
  2. Is there an issue with how the result is being assigned in the isolated context?
  3. Are there any limitations or special considerations for returning complex objects from isolated contexts?

DtonGamer avatar Nov 24 '25 13:11 DtonGamer

When I run your example I get:

Result type: object Reference {}
Actual result: { result: { processed: true, data: [ [Object] ] }, logs: [] }

This seems to be the expected result?

laverdet avatar Nov 24 '25 15:11 laverdet

When I run your example I get:

Result type: object Reference {}
Actual result: { result: { processed: true, data: [ [Object] ] }, logs: [] }

This seems to be the expected result?

The issue was that when i used isolated-vm, the result value was being retrieved from the isolate context as a
Reference object, but was not being properly copied to the main context using the .copy() method. This is what caused the
result to remain as an empty {} object instead of the actual execution result... i solved it buh thanks fren.

DtonGamer avatar Nov 25 '25 08:11 DtonGamer