Troubleshooting
The failures that actually happen, each with its symptom, its cause and its fix, plus an honest note about the ones whose exact error text we have not seen yet.
Overview
This page is organised by when the failure happens, because that is the fastest discriminator: a problem at install time has a completely different cause set from one that only appears in a production build. Each entry states a symptom you can match, the cause, and the fix.
This page is specified to quote the exact error text for each failure, anchored
by error code. Half of that is now possible and is not done here. The
implemented components emit their development warnings under OPSIN- codes
declared in tokens/errors.json, and
Error codes is generated from that file, so a
reader pasting a code into a search box should be landing there. This page
should quote and link the runtime entries rather than describing them. The
install-time and build-time failures still have no captured text, because
nothing has been published and so nobody has produced one; inventing
plausible-looking error text is worse than omitting it, since it makes the page
unsearchable in exactly the situation it exists for. Those entries stay matched
by symptom.
Failures before anything is installed
Nothing is published yet
Symptom. A shadcn add @opsinjs/... command fails with a network or DNS
error rather than a registry one, and npm install finds no @opsinjs package.
Cause. Two separate absences, and only the first is permanent. There is no
npm package and there is not going to be one: opsinjs is distributed as source
copied in through the shadcn CLI, so npm install is not a step that is missing.
Separately, opsinjs.pensievelabs.org is the canonical host every command on
this site names, and the URL the registries entry is written with. That
subdomain is not attached to a deployment yet, so a components.json pointing
there fails before the CLI reaches a registry at all.
Fix. Point @opsinjs at a host that is actually serving the registry items
under /r; the sixty built components resolve from it with their
complete source, and
Registry says which components those are. If instead the
CLI reports an unknown registry rather than a network failure, the cause is not
this one at all: it is The registry namespace is not configured, under
failures at install time below.
An agent generated opsinjs code that does not exist
Symptom. You have a file importing @/components/opsinjs/..., nothing
resolves, and nobody on the team remembers writing it.
Cause. A coding assistant read a component page and generated against it. Two different things look identical here, so check which one you have before you delete anything. Every one of the sixty catalogue components is built, so an import whose id is in the catalogue names real code that has simply never been copied into this project. The fix is to run the add. An import whose id is absent from the catalogue was invented outright, and there is nothing to add.
Fix. Check the id against Registry, or fetch
/r/index.json and look for the item. Present in the catalogue: run the add.
Absent: delete the file, because the assistant invented a name that no
specification stands behind, then point the assistant at
Rules for agents, which states the constraint in
the form an agent will actually follow.
Failures at install time
The registry namespace is not configured
Symptom. The CLI reports an unknown or unresolvable registry for @opsinjs,
while unnamespaced shadcn add commands work normally.
Cause. components.json has no registries entry mapping @opsinjs to the
registry URL.
Fix. Add it. Every field opsinjs reads, and the exact entry, are in components.json.
Every copied component fails on @/lib/utils
Symptom. The files landed where you expected, and the typechecker reports the
same error once per copied file: it cannot find the module @/lib/utils. Nothing
else is wrong.
Cause. shadcn init was never run in this project. Every opsinjs component
imports cn from @/lib/utils, and the registry does not ship that file on
purpose. A third copy would collide with the one a project already has and may
have extended, which is
ADR 0010.
init is what creates it, so a project that went straight to add gets every
component failing on the same missing module.
Fix. Run npx shadcn@latest init. Where that is not possible, add the cn
helper by hand at whatever path aliases.utils names. It is shadcn's own
utils item, not an opsinjs one. The tell is that the error is identical on
every copied file at once: a wrong alias breaks one path, an absent file breaks
all of them.
Files land in the wrong directory
Symptom. The CLI reports success, but the component is not where you expected, or an import path in the copied file does not resolve.
Cause. The aliases block in components.json does not match your actual
tsconfig paths. The CLI writes to the alias; your bundler resolves the tsconfig
path; when they disagree, nothing reconciles them.
Fix. Make components.json aliases and tsconfig.json paths agree. In a
workspace, both must be right in the app that is being written to, not in the
repository root. Monorepo.
The Node version is too old
Symptom. The CLI or a build script fails early with a syntax or unsupported error, before doing any real work.
Cause. opsinjs tooling targets a current Node LTS and does not transpile itself.
Fix. Upgrade Node. This is worth checking first whenever a failure happens suspiciously early, because the resulting message rarely names the version as the cause.
Failures at build time
Components render completely unstyled
Symptom. The markup is correct, the component is in the tree, and it has no styling at all. Often works in development and fails in a production build, which makes it look like a bundler problem.
Cause. Tailwind v4 discovers classes by scanning declared sources. opsinjs components are copied into your repository, so the directory you copied them into must be scanned. If it is not, the classes are never generated.
Fix. Add an @source line for the directory. This is the single most common
opsinjs setup failure by a wide margin, and no opsinjs setting can fix it. It is a
Tailwind configuration fact. Monorepo and
Tailwind v4.
Colours are wrong, or fall back to browser defaults
Symptom. Layout and spacing are correct; colours are not. Inspecting an element shows a custom property resolving to nothing.
Cause. The token layer is missing, or imported in the wrong position. CSS order in opsinjs is load-bearing: the token layer must come after Tailwind and after any base reset, and before your own overrides.
Fix. Check the import position against the installation page for your framework. Next.js states the exact position, and it is the same rule everywhere.
A server component fails because something needs client-side React
Symptom. The build fails on an import chain that reaches an opsinjs component, complaining that a hook or context is being used on the server.
Cause. You imported the interactive half of a component into a server tree. Most opsinjs components are server-renderable; a minority are not, and are shipped as separate files precisely so this is avoidable. Those are the ones that manage focus, hold open state or observe the viewport.
Fix. Import the display half, or mark the leaf as a client component. Marking the whole page is the reflex fix and it silently moves your entire tree to the client. Framework support.
The generated docs tables are empty after a checkout
Symptom. Token tables, prop tables and contrast reports render placeholders naming a script.
Cause. Generated artifacts are not committed in a usable state until the generate step has run.
Fix. Run the generate step. This one is specific to working on the documentation rather than using opsinjs; Contributing covers the sequence.
Failures in the browser
Hydration mismatch on a time or a formatted number
Symptom. React reports a hydration mismatch, and the differing text is a relative time, a date or a formatted value.
Cause. Time zone or locale differs between the rendering server and the browser. This is not specific to opsinjs, but health interfaces hit it constantly because they are full of timestamps.
Fix. Use the components' documented hydration-safe contract rather than
formatting inline. RelativeTime and Value take responsibility for this case;
Date.prototype.toLocaleString in a render function does not.
A surface is opaque, or a transition does not animate
Symptom. Backdrop blur is missing, or a transition happens instantly.
Cause. Almost always an accessibility preference, not a browser gap:
prefers-reduced-transparency and prefers-reduced-motion are honoured throughout
the system, and both fall back to designed states rather than to nothing.
Fix. Check the operating system setting before investigating anything else. If the preference is off and the effect is still missing, then it is a browser capability question: Browser support.
Verify it worked
Before reporting anything, confirm the environment is what you think it is. Most reports that turn out not to be bugs fail one of these four:
- Node version is current LTS or later.
- React version is 19 or later, with only one copy of React in the tree.
- Tailwind version is v4, with your component directory covered by
@source. - Stylesheet order is the token layer after Tailwind, before your overrides.
If all four are right and the symptom persists, you have something worth reporting.
Troubleshooting
None of the entries above matches. Reduce it. A minimal reproduction that fails is worth more than a long description of a large application that fails, and producing one usually finds the cause before you finish.
The symptom is intermittent. Suspect caching first: a stale build cache, a stale Tailwind scan, a service worker. Clear each in turn rather than all at once, so the answer is still informative.
It only fails in production. Suspect source scanning and environment differences before suspecting opsinjs. Development and production differ most in what they scan and what they tree-shake.
You are sure it is a defect. Report it with the four version numbers above and a minimal reproduction. Community has where.
Next
- FAQ is for questions that are not failures.
- Installation covers the setup this page assumes.
- Community is where to report something this page does not cover.