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.
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:
npm uninstall -g caret-cli
npm install -g caret-cli@latestOutput 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:
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:
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:
- Confirm
caret.mdexists at the project root (runcaret initwrites one automatically). - For Cursor / Claude Code: confirm the file is checked into the repo and not gitignored.
- Re-state the rules at the top of your prompt: "Use Caret components from ./caret. Don't import chalk or ora."
node --version, caret --version, your terminal, and echo $TERM $LANG.See FAQ for higher-level questions about why Caret behaves the way it does.