CLAUDE_CONFIG_DIR semantics inconsistent: settings.json under .claude/ but skills at root

Open 💬 2 comments Opened Apr 30, 2026 by renatogcarvalho

When CLAUDE_CONFIG_DIR is set, Claude Code resolves config paths inconsistently across files:

| File | Path scanned | Implies CLAUDE_CONFIG_DIR is... |
|---|---|---|
| settings.json | ${CLAUDE_CONFIG_DIR}/.claude/settings.json | parent of .claude/ (like ~) |
| User skills | ${CLAUDE_CONFIG_DIR}/skills/ | the .claude/ dir itself (like ~/.claude) |

Repro (Claude Code v2.1.122):

export CLAUDE_CONFIG_DIR=/tmp/cc-test
rm -rf "$CLAUDE_CONFIG_DIR"
mkdir -p "$CLAUDE_CONFIG_DIR/.claude/skills/foo" "$CLAUDE_CONFIG_DIR/skills/bar"

cat > "$CLAUDE_CONFIG_DIR/.claude/skills/foo/SKILL.md" <<'SKILL'
---
name: foo
description: Test skill placed under CLAUDE_CONFIG_DIR/.claude/skills/ (parent-of-.claude semantics).
---

# foo

When invoked, respond `foo invoked` and stop.
SKILL

cat > "$CLAUDE_CONFIG_DIR/skills/bar/SKILL.md" <<'SKILL'
---
name: bar
description: Test skill placed under CLAUDE_CONFIG_DIR/skills/ (config-dir-as-.claude semantics).
---

# bar

When invoked, respond `bar invoked` and stop.
SKILL

claude --setting-sources user --debug-file /tmp/cc.log -p "/foo"
# → Unknown command: /foo  (skill not registered)

claude --setting-sources user -p "/bar"
# → bar invoked         (skill registered and invocable)

grep "Loading skills" /tmp/cc.log
# → Loading skills from: managed=..., user=/tmp/cc-test/skills, project=[...]

The debug log confirms user-level skills are scanned at ${CLAUDE_CONFIG_DIR}/skills/ while settings.json resolves under ${CLAUDE_CONFIG_DIR}/.claude/.

Expected: consistent semantics — either both under .claude/ (treating CLAUDE_CONFIG_DIR as a parent) or both at the root (treating it as the .claude dir itself).

Impact: containerized/sandboxed Claude Code installs that anchor CLAUDE_CONFIG_DIR to a custom path lose user-level skill discovery without the inconsistency being documented anywhere. The official docs don't describe CLAUDE_CONFIG_DIR's layout in detail. Related: #3833.

Suggested fix: unify the path semantics, or document the layout explicitly so consumers can pick a CLAUDE_CONFIG_DIR value that works for both.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗