Skip to content

saveRun is last-write-wins: concurrent evaluations can silently clobber recorded outcomes #201

Description

@briananderson1222

Problem

saveRun persists a run as a plain whole-file writeJson of state + manifest + report with no compare-and-swap and no locking (dist/runtime/flow-run-store.js:160-164 in 1.3.0/1.4.x), and consumers hold no mutex around evaluate. Two concurrent evaluations of the same run — e.g. an in-process REST evaluate racing an out-of-process flow CLI against the same .flow/runs/<id>/ — are last-write-wins: one evaluation's recorded gate outcomes and transitions can be silently clobbered by the other's stale snapshot.

This is a run-integrity hazard (lost outcomes in the file of record), distinct from any consumer-side staleness. Found while reviewing a downstream consumer's post-evaluation read path; the consumer's own exposure is bounded (its read strictly follows its own write and can only observe newer true state), but the underlying store cannot protect two writers from each other.

Suggested direction

Either CAS on a run revision (reject the save if the on-disk revision moved; caller re-reads and re-applies), or an advisory lock file per run dir held across read-evaluate-write. Even detection-only (warn on revision mismatch) beats silent clobber.

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