Skip to content

2.0.0-rc.14: until() through a synchronous memo misses optimistic confirmation #3943

Closed

Description

@GabbeV

Describe the bug

On 2.0.0-rc.14, an action waiting with until() through a synchronous memo remains pending when the actual source confirms its optimistic prediction. Reading the optimistic accessor directly in the predicate completes the same action.

The predicate subscribes before confirmation arrives. The prediction alone correctly does not satisfy the wait, but confirming it does not resolve the wait through the memo either.

Your Example Website or App

https://s.olid.uk/?id=d1d1a3ee-70c8-4afe-966d-258809cb4f06

The playground uses published 2.0.0-rc.14. Here is the full component, including the actual source update in the Confirm button:

import { action, createMemo, createOptimistic, createSignal, until } from "solid-js";
import { render } from "solid-js/web";

function App() {
  const [source, setSource] = createSignal(0);
  const [count, guess] = createOptimistic(() => source());
  const doubled = createMemo(() => count() * 2);
  const [completed, setCompleted] = createSignal(false);

  const save = action(function* () {
    guess(1);
    yield Promise.resolve();
    // Direct-read control: yield until(() => count() === 1);
    yield until(() => doubled() === 2);
  });

  return (
    <main>
      <button onClick={() => save().then(() => setCompleted(true))}>1. Start</button>
      <button onClick={() => setSource(1)}>2. Confirm</button>
      <p>Displayed count: {count()}</p>
      <p>Doubled memo: {doubled()}</p>
      <p>Action completed: {String(completed())}</p>
    </main>
  );
}

render(() => <App />, document.getElementById("app")!);

Steps to Reproduce the Bug or Issue

  1. Open the playground and click 1. Start.
  2. The displayed count becomes 1 and the doubled memo becomes 2. Action completion remains false, as expected while the prediction is unconfirmed.
  3. Click 2. Confirm to set the actual source to 1.
  4. Action completion still remains false.
  5. Change the wait to yield until(() => count() === 1), rebuild, and repeat. Action completion becomes true after confirmation.

Both the failing memo case and the successful direct-read control were verified in the browser.

Expected behavior

The optimistic prediction alone should not satisfy until(). Once the actual source confirms the prediction, the predicate through the synchronous memo should resolve and the action should complete, just as the direct-read predicate does.

Platform

  • OS: Linux (WSL)
  • Browser: Chrome for Testing 153.0.8010.12, tested with Playwright
  • Solid: 2.0.0-rc.14

Activity

  1. reopened this on Oct 9, 2026
  2. ryansolid commented on Oct 11, 2026

    @ryansolid
    Member

    Fixed by #3978, merged into next as e0a7548: until() through a derivation of an optimistic value now resolves once the source confirms the guess, as the direct read already did. Your example (until(() => doubled() === 2)) is pinned in tests/until-memo-confirmation-3943.test.ts, along with the store form.

    The prediction alone still does not satisfy the wait: a guess made again after a confirmation, an unconfirmed guess the derivation reads, or a write the action still holds keeps until() waiting.

    Closing by hand, since merges into next don't close linked issues.

    — Claude via Claude Code


    Generated by Claude Code

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