Skip to content

[P0] Hook sandbox crashes on nested cross-object writes — forces denormalized workarounds across templates #1867

Description

@xuyushun441-sys

Problem

Hook handlers run in a single-suspended-async QuickJS (asyncify) sandbox. A hook that issues a nested engine write (e.g. ctx.api.object('parent').update(...) from a child's hook) re-enters the sandbox while the first call is suspended and crashes the process with memory access out of bounds.

Impact (platform-wide)

This single limitation forces a reaction-free, denormalized workaround across five shipped templates. Each CHARTER explicitly documents it as the reason header/rollup fields are hand-maintained:

  • expense_report.total_amount, procurement_order.received_amount, pm_project.progress_percent/actual_cost, content_publication.total_*, compliance rollups.

Authors cannot write the most natural automation ("when a child changes, update the parent").

Repro

Add an afterInsert/afterUpdate hook on a child object that calls ctx.api.object(parent).update(...); trigger it → process crash (memory access out of bounds). ctx.services.data is also undefined inside the sandbox (silent no-op), so the "obvious" alternative also fails.

Expected

Nested engine writes from a hook should be safe — e.g. queued and flushed after the current op commits, or hooks executed in a model that allows more than one suspended async call.

Affected

@objectstack/runtime (hook execution sandbox).


Found while runtime-testing objectstack-ai/templates (all 9 templates via objectstack dev all) on @objectstack 9.5.1. Build + typecheck pass; these only surface at runtime.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions