All docs
Reference · Troubleshooting

Troubleshooting

Most Caret problems trace to one of four causes: capability misdetection, missing runtime deps, font fallback for box-drawing glyphs, or stale registry. Quick triage by symptom below.

caret init / add fails

"Target directory exists"

init refuses to scaffold over an existing directory. Pick a fresh name or remove the existing one.

sh
rm -rf my-cli
npx caret-cli init my-cli

"Unknown component"

caret add printed an unknown name. Run caret list to see exact slugs (case matters — codeBlock not code-block).

"Could not locate Caret registry"

The CLI's registry resolver failed. Likely cause: you ran the CLI from a corrupted node_modules/caret-cli/registry/. Reinstall:

sh
npm uninstall -g caret-cli
npm install -g caret-cli@latest

Output looks wrong

Box-drawing characters misaligned

Symptoms: │ ├ └ ─ drift by a pixel between rows. Cause: terminal mixing two monospace fonts (one for letters, one for box-drawing). Caret can't fix this from the CLI side — the user's terminal needs a font that ships the full Unicode block-element + box-drawing range. Fonts that work: JetBrains Mono, Berkeley Mono, Iosevka, Cascadia Code.

No colors at all

Caret detected NO_COLOR, a non-TTY stdout, or TERM=dumb. Verify with:

sh
env | grep -E "NO_COLOR|FORCE_COLOR|TERM"
node -e "console.log(process.stdout.isTTY)"

If you want to force color in CI, set FORCE_COLOR=3. If you don't want color, that's working as designed — Caret respects every standard color-disabling signal.

Spinner shows squares instead of braille

Cause: terminal font missing the braille range (U+2800–U+28FF). Fix: set CARET_REDUCED_MOTION=1 to fall back to a static glyph, or switch to a font that ships braille.

Tables wrap or truncate ugly

Caret detects terminal width via process.stdout.columns and adapts. Resize the terminal, or pass an explicit width option to banner / table / paragraph.

Interactive components don't respond

"setRawMode is not a function"

Cause: process.stdin is not a TTY (piped input, running in a non-interactive shell). Interactive prompts only work in a TTY. For non-interactive flows, accept input via flags or environment variables instead.

Ctrl+C doesn't exit cleanly

Caret resolves prompts to null on Esc, throws CaretCancelled on Ctrl+C from caret.prompt wrappers. Catch it explicitly:

ts
import { CaretCancelled } from './caret'

try {
  const name = await prompt.text({ label: 'Project name' })
} catch (e) {
  if (e instanceof CaretCancelled) {
    process.exit(130) // standard SIGINT exit code
  }
  throw e
}

Theme issues

Brand accent not appearing

caret.theme.set must be called BEFORE the component renders. Calling it after the spinner has started won't repaint already-emitted output. Move it to the top of your main().

PartialTheme typing complains

Ensure you import PartialTheme from your local copy at caret/theme/types.ts (it lands there after npx caret add theme) and not the full Theme. PartialTheme makes every leaf optional.

AI assistants generate non-Caret code

Cause: caret.md isn't at the repo root, or the assistant isn't loading repo-level instructions. Fix:

  1. Confirm caret.md exists at the project root (run caret init writes one automatically).
  2. For Cursor / Claude Code: confirm the file is checked into the repo and not gitignored.
  3. Re-state the rules at the top of your prompt: "Use Caret components from ./caret. Don't import chalk or ora."
Still stuck?
Open an issue at github.com/gorkemyildiz/caret with the output of node --version, caret --version, your terminal, and echo $TERM $LANG.

See FAQ for higher-level questions about why Caret behaves the way it does.