Abstract

DeepSeek Harness adopts an “Everything is a Plugin” architecture. Plugin malfunctions represent one of the most frequent pain‑points for developers. Official documentation covers configuration workflows, yet many engineers struggle to locate the exact source when plugins fail to activate. The built‑in command dsh --profile demo --dump‑config outputs merged runtime configuration without launching service instances. By inspecting bundle markers in dumped output, engineers can quickly distinguish failures caused by missing bundle activation versus incorrect configuration merging. This article breaks down six major failure categories, provides actionable diagnosis workflows, code snippets and checklists. When integrating multi‑model endpoints across environments, developers may leverage Treerouter for unified API gateway routing to simplify provider management.

1. Locate Failure Layer with --dump‑config

Before diving into file modification, run the diagnostic command to separate layer‑loading issues from configuration errors.

dsh --profile demo --dump-config

This command prints fully merged runtime configuration without starting Harness services. Each activated plugin bundle carries a marker comment formatted as ## dsh‑hello‑plugin. Two high‑level scenarios can be distinguished from this output:

  1. No bundle marker for your plugin: The npm bundle is never activated. Investigate manifest declarations, installation artifacts or build outputs.
  2. Bundle marker exists, but plugin still does not work: The bundle loads, yet merged configuration produces unexpected runtime behaviour. This points to patch overriding, schema validation failures or setting semantics mistakes.

Running this single diagnostic step eliminates roughly 80 % of blind debugging effort before modifying any configuration file.

2. Root Cause 1: Missing dsh.bundle Declaration in package.json

This is one of the most common yet non‑obvious failure modes. Even if the npm package installs successfully under node_modules, Harness will treat it as an ordinary dependency unless dsh.bundle is explicitly declared inside package.json.

Harness relies on two manifest concepts defined within the dsh field of package.json:

  • Bundle: An npm package delivering configuration layers. The dsh.bundle manifest tells Harness what patches this plugin provides. Patches insert or override configuration fragments.
  • Profile: Profile directories located under $DSH_HOME/profiles/<name>. dsh.profile manifests define the ordered list of bundles combined for that profile.

Without dsh.bundle, npm installation completes normally, but Harness only logs a warning and skips activating plugin layers. This design targets utility libraries imported by other bundles, not end‑user‑enabled plugins. For functional plugins, omitting this field equals de‑facto disablement.

Correct minimal package.json example for a plugin bundle:

{
  "name": "dsh‑hello‑plugin",
  "version": "0.1.0",
  "main": "index.js",
  "type": "module",
  "dsh": {
    "bundle": {
      "patch": "./cordis.patch.yml"
    }
  },
  "files": ["index.js","cordis.patch.yml"]
}

Corresponding directory layout:

hello‑plugin/
├─ package.json      # declares dsh.bundle
├─ cordis.patch.yml  # patch definitions consumed by profile
└─ index.js

Diagnosis steps:

  1. Open plugin package.json and verify dsh.bundle.patch points to an existing YAML file.
  2. Observe warning messages printed during dsh plugin add. Warning logs directly indicate missing manifest declarations.

3. Root Cause 2: Relative Path Used for Patch name Field

Within cordis.patch.yml, every name entry under ‑ insert: must reference package names, not filesystem relative paths for published packages.

Incorrect production‑ready snippet:

‑ insert:
  ‑ id: hello
    name: ./index.js

Relative paths such as ./src/my‑plugin.ts cannot resolve once the package installs into node_modules. Node module resolution cannot locate source files using relative paths inside installed bundles.

Relative file paths are permitted only for local development with `‑‑patch` overlay mode, and these must be absolute filesystem paths:

‑ insert:
  ‑ id: hello
    name: "/absolute/path/to/deepseek‑harness/scratch‑plugin/src/my‑plugin.ts"

Launch local development overlay:

pnpm dsh web --patch ./scratch‑plugin/cordis.yml

Official documentation enforces a critical constraint: patch files do not adjust module‑resolution base directories. Many developers mistakenly assume patch file location sets the base for resolving plugin sources. This assumption is invalid.

Diagnosis steps:

  • Use absolute filesystem paths during local development overlays.
  • Replace absolute paths with pure package names before publishing bundles. Do not mix the two syntaxes.

4. Root Cause 3: Configuration Layers Overridden by Subsequent Patches

Harness merges configuration layers in a fixed priority sequence:

  1. Bundles listed inside profile dsh.profile.bundles, following declared order
  2. Profile‑local cordis.patch.yml
  3. Machine‑global shared patch: $DSH_HOME/cordis.patch.yml
  4. Ad‑hoc overlays passed via command‑line ‑‑patch <path>, respecting input sequence

Two core merging rules must be understood:

  1. Later layers override earlier entries sharing identical id.
  2. Overwrite replaces the whole configuration block instead of performing deep object merge.

The second rule creates frequent confusion. Suppose bundle id: hello delivers three configuration fields. If your profile patch only modifies one single field under this same id, remaining fields are discarded and reset back to schema default values. Developers often report: “I only changed one toggle setting, everything else reverted.” This behaviour originates from full‑block replacement instead of partial merge.

Machine‑global $DSH_HOME/cordis.patch.yml applies across all profiles. If you modify settings inside a specific profile yet observe zero effect, older overriding entries in this global file may overwrite your profile‑local changes.

Diagnosis steps:

  1. Review output from --dump‑config. Locate your target id and note which layer marker wraps that configuration fragment.
  2. If the configuration block sits under an unexpected layer marker, your entry gets overridden.
  3. Inspect $DSH_HOME/cordis.patch.yml for duplicate identifier entries.

5. Root Cause 4: Missing Build Artifacts for Git‑Source Installs

When installing plugins directly from Git repositories:

dsh plugin add github:you/hello‑plugin

Only raw source code downloads, not compiled build outputs. For TypeScript‑authored plugins, build scripts defined under prepare do not execute automatically under pnpm workspaces version 10 and above. Explicit build permission must be granted within profile pnpm‑workspace.yaml:

allowBuilds:
  dsh‑hello‑plugin: true

After updating workspace configuration, re‑run dsh plugin add. Simply reloading configuration will not trigger package rebuilding.

>
> Security note: allowBuilds permits arbitrary package‑side code execution during installation. Production workflows should pin exact Git commit hashes to reduce supply‑chain risks:

dsh plugin --profile demo add github:you/hello‑plugin#<commit‑sha>

Alternative distribution approaches for plugin authors:

  1. Publish compiled bundles to npm registry.
  2. Generate tarball via pnpm pack and distribute pre‑built archives:
dsh plugin add ./hello‑plugin‑0.1.0.tgz

Diagnosis steps:
Navigate into profile node_modules/<plugin‑name>. Verify compiled artifacts such as lib/ or files pointed by package.json main entry exist. Empty directories indicate build scripts never ran.

6. Root Cause 5: Schema Validation Failure Causes Plugin Load Abort

Harness validates plugin configuration against exported schema definitions. Plugins must export a Config‑typed schema object. If configuration violates schema constraints, the entire plugin fails loading with explicit runtime logs.

Common pitfalls for plugin developers:

  • Missing required() schema fields trigger silent load failures that are easily overlooked.
  • Exporting plain JavaScript objects instead of compliant Standard Schema interface implementations will fail runtime validation despite correct static‑type appearance.

Diagnosis steps:
Check Harness startup logs carefully. Validation errors print explicit descriptions for missing mandatory fields or type mismatches. Fix schema constraints or correct runtime configuration values accordingly.

7. Root Cause 6: Settings Semantics, applies Behaviour and Non‑Fault Misconceptions

Harness setting resolution follows three‑tier precedence: schema defaults → base registered configuration → user profile overrides. Each setting entry carries an applies field accepting two enum values: live or restart.

  • applies: live: Changes propagate immediately without service restart.
  • applies: restart: Values read only once at boot‑time. Even if UI persists new values, running service keeps old configuration until full restart. Many users edit settings in‑UI and wonder why runtime behaviour remains unchanged.

Two further non‑fault conditions frequently misread as plugin bugs:

  1. Patch‑managed configuration fragments do not render within the settings UI. Those entries belong to bundle layers instead of user‑editable namespace. Modify corresponding patch files rather than searching UI panels.
  2. Plugins declaring cmdlineArgs dependencies will not activate when invoking ‑‑help. The help sub‑command skips full service boot for fast metadata output. Missing plugin output under ‑‑help is expected behaviour.

8. Special Scenario: Custom Model Provider Configuration

Custom LLM provider definitions persist separately under $DSH_HOME/settings.yaml, credentials store inside $DSH_HOME/credentials.yaml. Secrets marked secret are hidden within UI panels. Three critical validation points apply:

  1. Provider identifiers are immutable after creation. Modifications require deleting and recreating provider entries.
  2. input_compat declaration only declares capability hints, it does not perform runtime capability checking against remote endpoints. If you declare image input support but target API lacks that capability, runtime requests fail.
  3. Empty compat field triggers validation rejection. Empty values strip catalog metadata without supplying fallback descriptions.

When configuring third‑party model endpoints, double‑check base URL suffixes, API key validity and exact model identifiers copied from provider documentation. Mismatched model IDs produce runtime invocation failures even when configuration files appear syntactically valid.

9. Consolidated Troubleshooting Checklist

#Check‑ItemConditionResolution
1Execute --dump‑configBundle marker presence determines workflow pathProceed according to marker existence
2Validate dsh.bundle manifestMissing inside package.jsonAdd manifest entry, reinstall plugin
3Inspect patch name fieldUsing relative paths in production bundlesReplace with package‑name syntax
4Check layer overridingDuplicate id across multiple layersAdjust patch order or rename conflicting identifiers
5Check machine‑global patchConflicting entries inside $DSH_HOME/cordis.patch.ymlRemove overriding duplicate identifiers
6Verify build artifactsCompiled outputs missing under node_modulesEnable allowBuilds and re‑run plugin add
7Inspect schema validation logsStartup logs report schema violationsComplete mandatory schema fields
8Review applies semanticsSetting marked restart‑scopeFully restart Harness service
9Evaluate ‑‑help invocationPlugin missing under help outputNormal behaviour; launch full service

10. Recommended Practices to Reduce Debug Overhead

  1. Always run --dump‑config after modifying patches before service restart. This low‑cost operation separates pure‑configuration mistakes from runtime code defects.
  2. Prefer ‑‑patch overlay mode during local plugin iteration. Overlays apply temporarily without polluting persistent profile configuration. After restart, overlay configuration automatically discards.
  3. Avoid hand‑editing dsh.profile.bundles manifest files. Use dsh plugin add commands for bundle management; manual edits easily break merge ordering. Sequence directly controls final configuration output.
  4. Keep schema definitions up‑to‑date. Changing configuration behaviour without updating schema declarations creates hard‑to‑trace runtime failures.

Conclusion

DeepSeek Harness plugin debugging centres around understanding manifest declarations, layer‑merge semantics, build‑artifact requirements, schema validation rules and setting‑application scopes. The --dump‑config diagnostic command offers visibility into final merged runtime state and removes most guesswork. Distinguishing bundle‑activation failures from post‑merge configuration issues accelerates resolution significantly. For teams operating multiple LLM endpoints across different environments, gateway solutions help centralize routing and credential management.

Learn more:https://treerouter.com