Description
When a sandboxed hook executes via QuickJSScriptRunner, the installCtx method calls setGlobalJson to serialize the hook context into the QuickJS sandbox. This calls JSON.stringify on the full context object. If the context (or anything reachable from it) holds a setTimeout/setInterval handle, JSON.stringify throws:
TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Timeout'
| property '_idlePrev' -> object with constructor 'TimersList'
--- property '_idleNext' closes the circle
The full stack trace:
TypeError: Converting circular structure to JSON
at JSON.stringify (<anonymous>)
at setGlobalJson (packages/runtime/dist/index.js)
at QuickJSScriptRunner.installCtx (packages/runtime/dist/index.js)
at QuickJSScriptRunner.execute (packages/runtime/dist/index.js)
at boundBodyHandler (packages/runtime/dist/index.js)
at runWithTimeout (packages/objectql/dist/index.mjs)
at runWithRetry (packages/objectql/dist/index.mjs)
at runWithErrorPolicy (packages/objectql/dist/index.mjs)
at Object.handler (packages/objectql/dist/index.mjs)
at _ObjectQL.triggerHooks (packages/objectql/dist/index.mjs)
Expected Behavior
setGlobalJson should strip or sanitize non-serializable host objects (Timers, streams, etc.) before passing to JSON.stringify, or use a replacer that safely skips them. At minimum, the error should be caught and reported clearly rather than surfacing as an opaque circular-reference crash.
Steps to Reproduce
Trigger any sandboxed hook when the ctx object tree contains a live setTimeout/setInterval handle.
Package(s) affected
packages/runtime — QuickJSScriptRunner.installCtx / setGlobalJson
Description
When a sandboxed hook executes via
QuickJSScriptRunner, theinstallCtxmethod callssetGlobalJsonto serialize the hook context into the QuickJS sandbox. This callsJSON.stringifyon the full context object. If the context (or anything reachable from it) holds asetTimeout/setIntervalhandle,JSON.stringifythrows:The full stack trace:
Expected Behavior
setGlobalJsonshould strip or sanitize non-serializable host objects (Timers, streams, etc.) before passing toJSON.stringify, or use a replacer that safely skips them. At minimum, the error should be caught and reported clearly rather than surfacing as an opaque circular-reference crash.Steps to Reproduce
Trigger any sandboxed hook when the
ctxobject tree contains a livesetTimeout/setIntervalhandle.Package(s) affected
packages/runtime—QuickJSScriptRunner.installCtx/setGlobalJson