Skip to content
Ilha
Esc
↑↓navigate↵open⌘Jpreview
On this page

ILHA002: Atom/watch slot count changed

A component created a different number of atom and watch slots on a later render.

Primitives are order-based. Ilha stores each atom() and watch() in a slot and matches slots to calls by position. When a render creates a different number of slots than the last one, Ilha warns with ILHA002.

Why it happens

You wrapped a primitive in a condition, a loop, or an early return, so the call count depends on state.

Bad

import { atom } from "ilha";

const Panel = ({ open }: { open: boolean }) => {
  if (open) {
    const draft = atom("");
    return <input value={draft()} />;
  }
  return <p>Closed</p>;
};

Fixed

Call primitives unconditionally and in the same order. Put the condition inside the view:

import { const atom: AtomFnatom } from "ilha";

const 
const Panel: ({ open }: {
    open: boolean;
}) => View
Panel
= ({ open: booleanopen }: { open: booleanopen: boolean }) => {
const const draft: AtomHandle<string>draft = atom<string>(init: string | Atom<string>, options?: AtomOptions<string> | undefined): AtomHandle<string> (+1 overload)
An existing Effect atom, or a plain value. Store a function with `atom.lazy(() => fn)`; the `ilha/oxlint` rule `function-in-atom` flags `atom(fn)`.
atom
("");
return open: booleanopen ? <JSX.IntrinsicElements.input: InputHTMLAttributesinput value?: Bindable<string | number> | undefinedvalue={
const draft: AtomHandle
() => string
draft
()} /> : <JSX.IntrinsicElements.p: HTMLAttributes<HTMLParagraphElement>p>Closed</JSX.IntrinsicElements.p: HTMLAttributes<HTMLParagraphElement>p>;
};

For one-time or conditional work, use atom.lazy(() => expensive()) or watch.once() instead of guarding the call.

Was this page helpful?