Skip to content
Latchkey

Qwik "eslint-plugin-qwik" use-method-usage lint failure in CI

Qwik use* hooks (useSignal, useStore, useTask$) must run synchronously at the top of a component$ body, like React's rules of hooks. eslint-plugin-qwik's use-method-usage rule fails CI when one is called conditionally, in a loop, or after an await.

What this error means

A lint step fails with "@builder.io/qwik/use-method-usage" reporting that a use* hook is called in an invalid location, such as inside a condition or after an async boundary.

eslint
error  Calling "useSignal" inside a condition or after an await is not allowed
  @builder.io/qwik/use-method-usage
  src/components/Form.tsx:11:20

Common causes

A use hook called conditionally or in a loop

Hooks must run in the same order every render; calling one inside an if or loop violates the rule.

A use hook after an await

Calling a use* hook after an async boundary in component$ breaks Qwik's hook ordering.

How to fix it

Call use hooks at the top, unconditionally

  1. Move every use* call to the top of the component$ body.
  2. Do not place them in conditions, loops, or after await.
  3. Re-run lint to confirm the rule passes.
src/components/Form.tsx
import { component$, useSignal, useStore } from '@builder.io/qwik';

export default component$(() => {
  const open = useSignal(false);       // top level
  const state = useStore({ count: 0 }); // top level, unconditional
  return <button onClick$={() => (open.value = !open.value)} />;
});

Keep the Qwik ESLint config

Run eslint-plugin-qwik in CI so invalid hook usage is caught before the build.

.github/workflows/ci.yml
npm run lint

How to prevent it

  • Call use* hooks only at the top of component$, unconditionally.
  • Never call a hook after an await or inside a branch.
  • Run eslint-plugin-qwik as a CI gate.

Related guides

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