Skip to content
Latchkey

SolidJS createSignal reactivity lost (build ok, test fails) in CI

A signal read outside a tracking scope (an effect, memo, or JSX) is captured once and never re-runs. The bundle compiles fine, but a test that mutates the signal then asserts on a plain variable sees the old value and fails in CI.

What this error means

vite build succeeds, but a Vitest run fails because a value derived from createSignal did not update after setX(...), so the assertion reads the initial value.

vitest
FAIL  src/counter.test.ts > increments count
AssertionError: expected 1 to be 2
  const [count, setCount] = createSignal(1);
  const doubled = count() * 2;  // read once, never reactive
  setCount(2);
  expect(doubled).toBe(4);

Common causes

A signal read outside a tracking scope

Calling the getter in plain code captures the value at that instant; later set calls do not re-evaluate it.

A derived value that is not a memo

Computing count() * 2 into a constant instead of a createMemo freezes it, so the test observes stale data.

How to fix it

Read signals inside a reactive primitive

  1. Wrap derived values in createMemo so they recompute on change.
  2. Assert after the reactive graph flushes, reading the getter again.
  3. For effects in tests, run them inside createRoot so disposal is controlled.
src/counter.test.ts
import { createSignal, createMemo } from 'solid-js';
const [count, setCount] = createSignal(1);
const doubled = createMemo(() => count() * 2);
setCount(2);
expect(doubled()).toBe(4);

Test effects inside createRoot

Solid effects need an owner; run them under createRoot so they track and dispose deterministically in CI.

src/counter.test.ts
import { createRoot } from 'solid-js';
createRoot(dispose => { /* create effects, assert, then */ dispose(); });

How to prevent it

  • Derive values with createMemo, not plain expressions.
  • Read signal getters inside effects, memos, or JSX only.
  • Wrap reactive test setup in createRoot.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →