Skip to content
Component installs need the registry setup— the Base UI shadcn project, the @vegastack namespace and the Cloudflare Access service token.
VegaStack Design

Troubleshooting

Exact error text → root cause → fix, for every failure mode hit while building the reference starter and running real consume tests.

Last updated

Errors below are verbatim from real runs. Find yours, apply the fix. If you hit something not listed, that's a doc bug — report it with the exact output.

Before reading further, run the setup check — it catches the most common misconfigurations, including the two silent ones below:

pnpm exec vegastack-design doctor

Install & build

Can't resolve 'tw-animate-css' in '…/node_modules/@vegastack/design'

Build error the moment preset.css is imported. Two different causes — check the second one first if you are on a current version.

Cause 1 (most likely today): no Tailwind PostCSS plugin. Without @tailwindcss/postcss configured, Tailwind's engine never runs, so the bundler's own CSS pipeline tries to resolve preset.css's @import "tw-animate-css" and fails. The error names a dependency, but the dependency is fine — nothing is missing. Under Turbopack (the Next 16 default) this fails the build; under webpack the import resolves and you get the silent variant instead (next entry). Fix: add the plugin, then rebuild.

postcss.config.mjs
const config = { plugins: { "@tailwindcss/postcss": {} } };
export default config;
pnpm add -D @tailwindcss/postcss

pnpm create next-app --tailwind writes this file for you, which is why the Quickstart never mentions it. Scaffolding by hand, adding VegaStack to an existing app, or building a monorepo app all skip that step.

Cause 2 (legacy): @vegastack/design older than 0.1.1, which marked tw-animate-css as an optional peer that pnpm never installs. Fix: pnpm update @vegastack/design (≥ 0.1.1). If you are already on a newer version, this is not your problem — see Cause 1.

Build succeeds, colours and fonts work, but no utility classes exist

The worst failure mode in the consume path, because nothing errors. p-4, flex, text-muted-foreground and every other utility do nothing, while the theme looks broadly right.

Cause: no @tailwindcss/postcss plugin (as above). The token theme is literal CSS inside preset.css, so :root/.dark custom properties land regardless — but every utility class has to be generated by Tailwind, and without the plugin Tailwind never runs. The result reads as "the design system is broken" when the design system was never invoked. Fix: the postcss.config.mjs above. Confirm it: the emitted stylesheet should contain real utility selectors, not just variables.

# after a build — expect a non-trivial count, not 0
grep -o '\.[a-z][a-z0-9-]*{' .next/static/**/*.css | wc -l

Cannot find module '@vegastack/design/theme.css' (or base/utilities)

Cause: an import path outside the exports map — usually @vegastack/design-tokens/theme.css in an app that never installed the tokens package (it's transitive; pnpm-strict hides it). Fix: import the re-exports: @vegastack/design/theme.css etc. Apps should never import @vegastack/design-tokens/* directly.

Tailwind utilities exist but everything is unstyled

Cause: app/globals.css still contains create-next-app's own @import "tailwindcss" block instead of (or as well as) the preset. Fix: the file should contain exactly one entry: @import '@vegastack/design/preset.css'; — the preset imports Tailwind itself.

Registry & CLI

shadcn add403 (or "Failed to fetch registry")

curl -s -o /dev/null -w "%{http_code}" \
  -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \
  -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET" \
  https://design.vegastack.com/r/registry.json
  • curl 403 too → the values are wrong: expired token, or the classic header-name-in-value mistake (CF-Access-Client-Id: abc… stored as the value). See Registry access & auth.
  • curl 200 but the CLI fails → the CLI isn't seeing your env: .env.local not in the directory you're running from, or the shell doesn't export the vars. Run from the project root; check components.json uses ${CF_ACCESS_CLIENT_ID} placeholder syntax exactly.

Component installed but looks/behaves wrong (Radix imports inside)

Cause: a bare shadcn add dialog — without @vegastack/, you got shadcn's own Radix-based component (and possibly overwrote ours). Fix: git checkout the file, re-add with the namespace: pnpm dlx shadcn@latest add @vegastack/dialog. Grep check: grep -r "@radix-ui" components/ui/ should return nothing.

shadcn init hangs forever

Cause: the CLI is waiting on an interactive prompt (non-tty shells, CI, agents). Fix: skip init — write components.json yourself; the complete known-good file is in the Quickstart §4. Init is a convenience, not a requirement.

vegastack-design: command not found

Cause: running it bare, outside a project that has @vegastack/design installed. Fix: pnpm exec vegastack-design … inside the project (the bin ships with the package), or one-off anywhere: npx --package=@vegastack/design vegastack-design ….

Runtime

toast(...) does nothing — no error, no toast

The #1 report. Cause: no VegaStackProvider above the calling component (or at all). Fix: Provider setup. Related: toasts appearing twice → two Toasters mounted; pass toaster={false} to one.

Hydration warning: server class="…" didn't match client, mentions <html>

Cause: missing suppressHydrationWarning on <html> — next-themes sets the theme class pre-hydration. Fix: add the attribute (Quickstart §6). This suppresses only that one attribute's check, nothing else.

Dialog / dropdown renders under the page header

Cause: the body { isolation: isolate } stacking context from base.css isn't applied — usually a granular-import setup that skipped base.css, or a CSS layer conflict overriding isolation. Fix: import the preset (it includes base.css), or re-add body { isolation: isolate }. Never "fix" this with z-index arms races.

No focus ring anywhere when tabbing

Cause: same as above — base.css skipped. Components intentionally carry no per-component focus ring; the global :focus-visible layer is the mechanism. Fix: import the preset. This is a WCAG failure, not a cosmetic issue — treat as ship-blocking.

Tooltips each wait ~600ms even when moving across a toolbar

Cause: no provider → no shared Base UI Tooltip.Provider delay group. Fix: Provider setup.

Updates

check-updates says "No VegaStack components found" despite copied components

Cause 1 (layout): it is looking in the wrong directory. It resolves components.json's aliases.ui by stripping a leading @/, then tries that path and a src/ variant. Any layout those two guesses miss — a monorepo package, or a @/* alias mapped somewhere else through tsconfig paths — scans nothing. Fix: point it at the real directory.

vegastack-design check-updates --dir packages/ui/src/components/ui

Make that the committed form of the script, not something you type once. A drift gate scanning the wrong directory is worse than no gate — which is why --fail-on-update now exits 1 when it finds zero components, instead of passing vacuously.

Cause 2 (legacy): @vegastack/design older than 0.1.1, whose check-updates only recognized files with provenance headers — which the current shadcn CLI strips on copy-in. Fix: pnpm update @vegastack/design. Current versions identify components by filename against the registry index and compare content — no header needed.

check-updates says up to date but the registry version number is higher

Not a bug. Status is by content hash, not version: the global version bumped but that component's bytes didn't change. Nothing to pull.

? <name> — not in registry (renamed/removed)

The component was renamed or retired upstream. Check the Changelog for the mapping; the copy in your repo keeps working regardless (you own it) — migrate when convenient. Caveat: this status only appears for files that still carry a provenance header (older CLIs / other tooling). A headerless copy of a retired component silently drops out of the report — after a rename lands in the changelog, grep components/ui/ for the old filename yourself.

--overwrite clobbered my customizations

Expected — overwrite replaces the file. Your edits are in git: git diff HEAD~1 -- components/ui/<name>.tsx, re-apply on top, run your smoke tests. Prevention: review with --diff first, keep customizations additive, or compose in wrapper files instead of editing the copy.

For agents: prefer exact-error-text search on this page over improvising. If a fix requires credentials or accounts (tokens, npm, Cloudflare), surface to a human — never work around an auth boundary.

On this page