Skip to content

engine: markNodeOffline performs four row-set updates plus invocation reschedule with no enclosing transaction #285

Description

@willwashburn

Severity: medium · packages/engine/src/engine/node.ts:512-565

The node-offline transition writes nodes, nodeProviders, agents, then calls rescheduleInvocationsForLostNode — four sequential await db.update(...) calls plus the reschedule, each its own statement, with no runAtomic wrapper. Contrast registerNode's broker path (node.ts:394-412) and bindAgentToNode (node.ts:1000), which are transactional. serializeNodeOp gives isolation but no atomicity/rollback.

Failure scenario: node marked offline and providers zeroed, but the process dies before rescheduleInvocationsForLostNode — in-flight invocations dispatched to the dead node stay dispatched and are only recovered by the dispatch-timeout sweep (up to ACTION_DISPATCH_TIMEOUT_MS + sweep interval of added latency), and agents can be left offline while their agent_node_bindings row is still active.

Fix: wrap the transition in runAtomic like its siblings.


Found during a multi-agent reliability review of the relay tool/protocol.

Metadata

Metadata

Assignees

No one assigned

    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