Home/Guides/Troubleshooting

DSH plugin not loading

Nine causes, ordered by how often they turn out to be the answer. Stop at the one that matches.

The failure mode that wastes the most time in this ecosystem is silence. A plugin that crashes shows you a stack trace. A plugin that never registered shows you nothing — the runtime starts fine, the command just is not there, and there is no error to search for. Before you assume the plugin is broken, rule out these nine.

1. The name you registered is not the name it exports

By far the most common cause. You installed a repository called dsh-something-helper, so you added dsh-something-helper to your config. The package exports something-helper, or @owner/something. Nothing matches, nothing loads, no error.

Check the name field in the plugin's package.json, not the repository name. Repository names are chosen for GitHub search; package names are chosen for the registry.

2. Scoped vs unscoped

Related to the above, and worth its own line because it bites people who already knew about #1. @acme/dsh-router and dsh-router are different strings. If the package is scoped and you registered it unscoped, or the reverse, it will not resolve.

3. You did not rebuild

TypeScript and JavaScript plugins usually ship source, not a build. If the package.json has a build script and you skipped npm run build, the entry point file does not exist yet. The loader reads the path, finds nothing, and moves on quietly.

cd plugins/your-plugin
npm install
npm run build

4. The entry point in package.json points somewhere else

Open package.json and look at main, module and exports. A project that restructured its source tree without updating these will appear to install correctly and load nothing. If the path in main does not exist on disk, that is your answer.

5. Provider plugins need a prefix, not just a registration

Model provider plugins are the exception to the general pattern: registering them is not enough, because they exist to intercept requests. A provider that takes over deepseek/ requests has to be registered and configured with that prefix, and the prefix has to match what your model string actually says.

If you registered a provider and your requests still go to the default upstream, check the model identifier you are using against the prefix the plugin documents. Mismatched prefix means the request never reaches your plugin. The Models & Routing category lists the routing plugins and what each one claims to intercept.

6. Ordering

Plugins that wrap other plugins — routers, loggers, memory layers, anything that instruments — must load before the thing they instrument. If you put a request logger after the provider it is meant to observe in your config, it observes nothing and reports nothing, which looks identical to being broken.

7. Permissions

Plugins that touch the filesystem, the shell or the network usually require an explicit permission grant. Denials are logged inconsistently across the ecosystem — some versions throw, most just return early. If the plugin has a permissions section in its README, read it before assuming the code is at fault.

8. Version mismatch with the runtime

The ecosystem moved fast in 2026. A plugin written against an older runtime can install cleanly and still fail to register, because the registration API changed shape. Check the last push date on the plugin against the runtime version you are running. This is the single best argument for the freshness markers on our plugin index: a plugin untouched since early 2026 is a plugin written against a different runtime.

9. It genuinely is broken

After all of the above: open an issue. Include the plugin version, runtime version, your registration snippet, and the output of a run with verbose logging. Nine times out of ten the maintainer's first reply is one of items 1–8, which is why you checked them first.

Debugging order, condensed

  1. Does the entry file in package.json exist on disk?
  2. Does the registered name exactly match package.json name?
  3. Did you run the build step?
  4. Is a provider prefix involved, and does it match your model string?
  5. Is this an instrumenting plugin loaded after its target?

Five checks, two minutes, and they resolve most of the issues filed in this ecosystem. For the wider picture — what plugins exist and which are still maintained — start from the full index.