Skip to content
Latchkey

Qwik "Code ... captured ... but is not serializable" in CI

Qwik serializes state across the server/client boundary so it can resume without replaying JS. Inside a $ closure (component$, useTask$), every captured value must be serializable. Capturing a class instance, DOM node, or function throws at build or runtime.

What this error means

The build or a runtime check fails with "Code ... captured a value ... but it is not serializable", naming the variable captured inside a $ boundary.

qwik
Error: Code(QRL) that was dynamically imported "src/routes/index.tsx"
captured a value "logger" but it is not serializable:
  [object Object] (class instance)

Common causes

A non-serializable value captured in a $ closure

Class instances, functions, DOM references, and symbols cannot be serialized, so capturing them across a $ boundary fails.

A closure that should have been a QRL

Passing a bare function where Qwik expects a lazy $(...) boundary captures the function itself, which is not serializable.

How to fix it

Capture only serializable values

  1. Move non-serializable objects (loggers, clients) into the closure body instead of capturing them.
  2. Recreate them inside the $ function, or use useStore for serializable state.
  3. Wrap callbacks in $(...) so Qwik stores a QRL, not the raw function.
src/routes/index.tsx
import { component$, useTask$ } from '@builder.io/qwik';

export default component$(() => {
  useTask$(() => {
    const logger = createLogger(); // created inside, not captured
    logger.info('run');
  });
});

Keep state in useStore / useSignal

Store serializable primitives and plain objects in Qwik state containers so they cross the boundary cleanly.

src/routes/index.tsx
import { useStore } from '@builder.io/qwik';
const state = useStore({ count: 0 });

How to prevent it

  • Capture only serializable data inside $ boundaries.
  • Create clients/loggers inside the closure, not outside it.
  • Use useStore/useSignal for shared state.

Related guides

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