Skip to content
Latchkey

Qwik "server$" function serialization error in CI

Qwik server$ turns a function into a server RPC. Its arguments and captured values must be serializable, and it runs only on the server. Capturing a client object or passing a non-serializable argument breaks the boundary at build or call time.

What this error means

The build fails, or a request errors, because a server$ function captured a non-serializable value or received an argument (a DOM node, a function) Qwik cannot serialize.

qwik
Error: Serialization Error inside server$():
  argument at index 0 is not serializable: [object HTMLInputElement]

Common causes

Non-serializable arguments to server$

Passing DOM nodes, class instances, or functions into a server$ call cannot be serialized to the server.

Captured client-only values

A server$ closure that captures browser objects fails because those cannot exist server side.

How to fix it

Pass only serializable arguments

  1. Extract primitives/plain objects from DOM values before calling server$.
  2. Do not capture client objects inside the server$ function.
  3. Return serializable data for the client to use.
src/routes/form.tsx
import { server$ } from '@builder.io/qwik-city';

const save = server$(async function (value: string) {
  return db.save(value); // value is serializable
});
// call with a primitive, not the input element
await save(inputEl.value);

Use routeAction$ for form data

For form submissions, routeAction$ handles serializable form data across the boundary cleanly.

How to prevent it

  • Send primitives and plain objects to server$, never DOM nodes.
  • Avoid capturing client-only values in server functions.
  • Prefer routeAction$/routeLoader$ for form and load data.

Related guides

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