[BUG] `--plugin-dir` silently drops all but the last directory when specified multiple times

Resolved 💬 3 comments Opened Feb 18, 2026 by pers0n4 Closed Feb 21, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

When loading multiple plugins via --plugin-dir, only the last directory takes effect — all earlier directories are silently discarded. This happens with both the repeated-flag form (--plugin-dir A --plugin-dir B) and the variadic form (--plugin-dir A B).

The CLI help explicitly advertises multi-directory support:

--plugin-dir <paths...>    Load plugins from directories for this session only (repeatable)

Single plugin works correctly; multiple plugins fail silently.

What Should Happen?

All specified plugin directories should be loaded. claude --plugin-dir ./pluginA --plugin-dir ./pluginB should load both pluginA and pluginB.

Error Messages/Logs

No errors or warnings are emitted. The earlier --plugin-dir values are silently discarded.

Steps to Reproduce

A full reproduction repository is available at:
https://github.com/pers0n4/claude-code/tree/fix/plugin-dir-multi-load-repro/repro/plugin-dir-multi-load

1. Create two minimal test plugins

Each plugin has a single SessionStart hook that writes a unique marker file to /tmp/.

plugin-alpha/                       plugin-beta/
├── .claude-plugin/                 ├── .claude-plugin/
│   └── plugin.json                 │   └── plugin.json
└── hooks/                          └── hooks/
    ├── hooks.json                      ├── hooks.json
    └── session-start.mjs               └── session-start.mjs
          ↓ writes alpha-loaded.txt           ↓ writes beta-loaded.txt

<details>
<summary>plugin-alpha source (click to expand)</summary>

.claude-plugin/plugin.json:

{
  "name": "plugin-alpha",
  "version": "0.0.1",
  "description": "Minimal test plugin A for --plugin-dir verification"
}

hooks/hooks.json:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.mjs\"",
            "timeout": 5
          }
        ]
      }
    ]
  }
}

hooks/session-start.mjs:

import { writeFileSync, mkdirSync } from "node:fs";

const dir = "/tmp/plugin-dir-repro-results";
mkdirSync(dir, { recursive: true });
writeFileSync(
  `${dir}/alpha-loaded.txt`,
  `alpha loaded at ${new Date().toISOString()}\n`,
  { flag: "a" },
);
console.log(JSON.stringify({ continue: true }));

</details>

plugin-beta is identical except it writes beta-loaded.txt.

2. Run the tests
# Clone the repro and cd into it
git clone -b fix/plugin-dir-multi-load-repro https://github.com/pers0n4/claude-code.git /tmp/repro
cd /tmp/repro/repro/plugin-dir-multi-load

# Or run the automated test script:
bash run-test.sh

Manual steps:

ALPHA=/tmp/repro/repro/plugin-dir-multi-load/plugin-alpha
BETA=/tmp/repro/repro/plugin-dir-multi-load/plugin-beta
RESULTS=/tmp/plugin-dir-repro-results

# Single directory — works correctly
rm -rf $RESULTS
claude --plugin-dir $ALPHA -p "say hi"
ls $RESULTS/          # → alpha-loaded.txt  ✅

rm -rf $RESULTS
claude --plugin-dir $BETA -p "say hi"
ls $RESULTS/          # → beta-loaded.txt   ✅

# Multiple directories — only last one loads (BUG)
rm -rf $RESULTS
claude --plugin-dir $ALPHA --plugin-dir $BETA -p "say hi"
ls $RESULTS/          # → beta-loaded.txt only  ❌ (alpha missing)

rm -rf $RESULTS
claude --plugin-dir $BETA --plugin-dir $ALPHA -p "say hi"
ls $RESULTS/          # → alpha-loaded.txt only  ❌ (beta missing)

# Variadic syntax — same bug
rm -rf $RESULTS
claude --plugin-dir $ALPHA $BETA -p "say hi"
ls $RESULTS/          # → beta-loaded.txt only  ❌ (alpha missing)
3. Result matrix

| Command | alpha-loaded.txt | beta-loaded.txt | Status |
|---------|:---:|:---:|:---:|
| --plugin-dir alpha | Yes | — | Pass |
| --plugin-dir beta | — | Yes | Pass |
| --plugin-dir alpha --plugin-dir beta | No | Yes | Fail |
| --plugin-dir beta --plugin-dir alpha | Yes | No | Fail |
| --plugin-dir alpha beta (variadic) | No | Yes | Fail |

Result: In every multi-directory case, only the last directory's plugin is loaded.

Claude Code Version

2.1.45 (Claude Code)

Operating System

macOS 26.3

Terminal/Shell

Ghostty/zsh

Additional Information

Root cause hypothesis:
The CLI help defines --plugin-dir as <paths...> (variadic) with (repeatable), which suggests the argument parser collects multiple values into an array. However, the downstream plugin loading code appears to only consume the last element of that array — either by treating it as a scalar string or by iterating but overwriting state on each pass.

Workaround:
Install one plugin permanently via claude plugin add, then use --plugin-dir for the remaining plugin that needs local testing.

Reproduction repository:
https://github.com/pers0n4/claude-code/tree/fix/plugin-dir-multi-load-repro/repro/plugin-dir-multi-load

Includes:

  • Two minimal test plugins (plugin-alpha, plugin-beta)
  • Automated test script (run-test.sh)
  • README with expected vs actual results

View original on GitHub ↗

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