Skip to content

AtomRegistry.batch drops Atom.fn writes from commit listeners #8546

Description

@schickling-assistant

A subscription callback that writes an Atom.fn while AtomRegistry.batch() is committing loses that write permanently. This occurs with a synchronously available source value; moving the source response to a later tick avoids it. The callback is a normal registry subscription, and the write is a normal registry.set.

Reproduction

Install effect@4.0.0-rc.117 and run this with Bun (bun repro.ts):

import assert from 'node:assert/strict'
import { Effect } from 'effect'
import * as Atom from 'effect/unstable/reactivity/Atom'
import * as AtomRegistry from 'effect/unstable/reactivity/AtomRegistry'

const registry = AtomRegistry.make()
const source = Atom.make(0)
const write = Atom.fn((value: number, get) =>
  Effect.sync(() => get.registry.set(source, value)),
)
const seen: number[] = []
registry.mount(write)
registry.subscribe(source, (value) => seen.push(value))
registry.subscribe(source, (value) => {
  if (value === 1) registry.set(write, 2)
})

AtomRegistry.batch(() => registry.set(source, 1))
console.log({ source: registry.get(source), seen })
assert.equal(registry.get(source), 2)
assert.deepEqual(seen, [1, 2])

Expected: source: 2, seen: [1, 2]. Actual: source: 1, seen: [1]; the first assertion fails (1 !== 2).

Atom.fn's write calls batch() internally. During the outer batch's notify/commit loop, that nested batch changes the shared phase back to collect and queues the function node for rebuild. Its depth is 2 so it does not flush; the outer batch has already completed its stale rebuild pass. The queued rebuild is then discarded when the outer batch clears stale, without running the function. Nested batches entered from commit callbacks need their stale rebuilds flushed before the outer commit finishes.

Versions: effect@4.0.0-rc.117, Bun 1.4.2, Linux x64. Also observed in the consuming app on effect@4.0.0-rc.112.

Posted on behalf of @schickling
field value
agent_identity dev3.direct.omp.de5nueza
session unknown
agent_persona generalist
agent_supervisor unavailable
agent_tool OMP
agent_tool_version 18.3.0
agent_runtime OMP 18.3.0
agent_model openai-codex/gpt-6-sol
worktree unknown
tooling_profile dotfiles@bcd0eca

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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