DeepSeek Harness: Unknown agent preset after plugin disable

TroubleshootingPublished 2026-10-20Author: DeepSeek Plugin Market
DeepSeek Harnessagent presetinjectCordisplugin loadingpending
The host boots, but new sessions fail with Unknown agent preset standard because a preset row waits on a service a disabled plugin used to provide.

Disabling one rarely used plugin leaves DeepSeek Harness (DSH) able to start, yet no new session can be created. The disabled plugin used to provide a service, the preset row names that service in inject, and inject is a hard dependency in Cordis. The row does not fail; it waits in pending indefinitely. Boot never resolves a preset, so the host looks healthy until a new session tries to resolve one.

DeepSeek Harness symptoms: host boots, sessions fail

The split between a healthy host and broken session creation is the signature: boot does not need a preset, while a new session does. Compare the symptoms before touching anything:

ActionObserved resultWhat it tells you
Start the hostsucceedsstartup does not resolve presets
Open an existing sessionusually succeedsits preset is already fixed in the session header
Create a sessionagent-preset/not-found: Unknown agent preset: standardthe preset row is not registered
Inspect the plugin listpending (waiting for service: xxx)an inject dependency is missing

Then confirm the chain:

  1. Read the waiting service name — open the plugin list and find the row marked pending; expected: it names a specific service, not a generic failure.
  2. Find the provider — search the list for the plugin that offers that service; expected: it is currently disabled.
  3. Re-enable it temporarily — turn the provider back on and wait for active; expected: the new-session error disappears at once.

According to the source review in the discussion, vendor/cordis/src/registry.ts:71-88 normalizes inject without a required/optional distinction, so every key is treated as hard; app-boot/src/index.ts:323/331 defaults requiredIds to an empty array, and :399-405 checks requiredIds before excluding pending rows, leaving only a warning (#10099). For normal preset setup, see agent presets.

Why pending is silent and DSH sessions still fail

Pending is a wait, not a crash, and the wait is only visible at the moment a preset must be resolved. Trace it:

  • Disable provider A — the service S it offered no longer exists, with no immediate error anywhere.
  • Leave S in the preset row's inject — Cordis refuses to start that row until S appears, so the row shows pending.
  • Start the host — only the base bundle is required, so startup succeeds without the preset row.
  • Create a session — the runtime looks for standard in the registry and reports agent-preset/not-found because the row never started.

That is why the failure looks like corrupted session data even though only a preset is missing.

Three DeepSeek Harness repair paths

Bottom line: re-enable the provider when you need a session now, patch inject when the plugin must stay off, and change the loader when you maintain a fork.

Path 1: re-enable the plugin that provides the service

This is the fastest recovery, and it means giving up the disablement; use it when the plugin was only switched off temporarily. Follow the provider chain:

  1. Note the missing service — read the pending row's waiting for service text; expected: one concrete service name.
  2. Locate its provider — search the plugin list for that service; expected: the provider is the disabled entry.
  3. Enable it — switch it on and wait for active; expected: the pending row starts.
  4. Create a session — choose the standard preset and send a message; expected: no Unknown agent preset.
  5. Fix a broken provider first if needed — if it fails to start, treat that as the real fault; expected: enabling a healthy provider clears both symptoms.

Path 2: blank or relax the preset row's inject

When the plugin must stay disabled and the preset does not truly need its service, override the row from the profile layer instead of editing the plugin.

  1. Open the patch file — edit ~/.dsh/profiles/<profile>/cordis.patch.yml; expected: you are in the profile layer, not the plugin source.
  2. Identify the row — locate the preset row id and read its current inject list; expected: every hard dependency is visible.
  3. Replace the list — add a patch for the same id with inject set to null; expected: the whole key is replaced, not merged.
  4. Restart — relaunch DSH and inspect that row; expected: it no longer waits for a service.
  5. Create a session — resolve the preset and send a message; expected: the preset loads, and you can note any tool that disappeared.

Blanking inject removes every dependency on that row, including services the preset genuinely needs, so only use it when the row is thin. The patch replaces the block, so a partial rewrite can erase other fields; back up first. Row ids change across plugin upgrades, which silently invalidates the patch.

Path 3: teach the loader optional dependencies and timeouts

The durable fix is to let inject express required versus optional, and to degrade instead of waiting forever. This path suits a fork or an upstream contribution:

  1. Extend normalization — in vendor/cordis/src/registry.ts, accept a shape such as { required: [...], optional: [...] }; expected: the two kinds are distinguishable.
  2. Stop blocking on optional — read optional dependencies with get() and return undefined when absent; expected: the row starts without the provider.
  3. Adjust the pending rule — in app-boot/src/index.ts:399-405, treat a row whose only missing dependencies are optional as usable; expected: it becomes active.
  4. Warn instead of silence — emit a warning that names the missing service; expected: the degradation is visible in the log.
  5. Test the disablement — disable the provider and create a session; expected: the preset still resolves with reduced capability.

Verify DSH recovery and avoid regressions

Do not stop at a single successful session; the preset must survive restarts and toggling. Check these points:

  1. Inspect the row — after restart, confirm it is no longer pending; expected: active, or gone if you removed it deliberately.
  2. Exercise the preset — create a session and send a message that invokes a tool; expected: the preset resolves and the tool runs.
  3. Open an old session — load one created before the change; expected: its existing tools still work.
  4. Toggle once more — disable and re-enable the provider; expected: the state changes cleanly with no leftover pending row.

Avoid these traps:

  • Do not dismiss pending as harmless: it means a capability never loaded, and it usually surfaces later as a feature that quietly vanished.
  • requiredIds defaults to empty in the current implementation, so boot will not fail for you; monitor the pending list yourself.
  • Patch precedence follows file order, so rule out a second patch that restores inject before debugging further.
  • No official fix version is named; 0.2.1-rc.2 still reproduces, so consult release notes and do not read an old DSH plugin pending state as current behavior.

DeepSeek Harness agent preset FAQ

Q: How do I fix DeepSeek Harness Unknown agent preset after disabling a plugin? A: DeepSeek Harness reports Unknown agent preset because the preset row lists a service from the disabled plugin in inject, and inject is a hard dependency in Cordis, so the row sits in pending. Startup does not resolve presets, but creating a session does; re-enable the plugin or blank that inject list.

Q: Why does a DeepSeek Harness plugin stay pending with no error in the log? A: A DeepSeek Harness plugin stays pending when its inject dependencies are not ready, typically because a provider is disabled, a version mismatched, or a dependency row failed. Unlike failed, pending does not block host startup, which is why it is easy to miss; read the service name and check its provider.

Q: What is the difference between inject and an optional dependency in DeepSeek Harness? A: DeepSeek Harness treats keys written into inject as hard dependencies; Cordis waits for them before starting the row. Optional capabilities should be read with get() or declared as optional services, because putting an optional tool into inject turns the whole row pending when it is disabled.

Q: Why is the DeepSeek Harness preset row still pending after setting inject: null? A: A DeepSeek Harness preset row can stay pending if the patch deep-merges instead of replacing the block, or if it targets the wrong row id. Check for a second patch that writes inject back, apply order matters, then clear the profile build cache and restart.

FAQ

How do I fix DeepSeek Harness Unknown agent preset after disabling a plugin?

DeepSeek Harness reports Unknown agent preset because the preset row lists a service from the disabled plugin in inject, and inject is a hard dependency in Cordis, so the row sits in pending. Startup does not resolve presets, but creating a session does; re-enable the plugin or blank that inject list.

Why does a DeepSeek Harness plugin stay pending with no error in the log?

A DeepSeek Harness plugin stays pending when its inject dependencies are not ready, typically because a provider is disabled, a version mismatched, or a dependency row failed. Unlike failed, pending does not block host startup, which is why it is easy to miss; read the service name and check its provider.

What is the difference between inject and an optional dependency in DeepSeek Harness?

DeepSeek Harness treats keys written into inject as hard dependencies; Cordis waits for them before starting the row. Optional capabilities should be read with get() or declared as optional services, because putting an optional tool into inject turns the whole row pending when it is disabled.

Why is the DeepSeek Harness preset row still pending after setting inject: null?

A DeepSeek Harness preset row can stay pending if the patch deep-merges instead of replacing the block, or if it targets the wrong row id. Check for a second patch that writes inject back, apply order matters, then clear the profile build cache and restart.

Related Terms

inject
inject is the Cordis mechanism for declaring service dependencies. Names listed in inject are hard dependencies; a plugin waits in pending rather than erroring when they are missing. It suits required services, not optional capabilities.— https://github.com/deepseek-ai/deepseek-harness/discussions/10099
agent preset
agent preset is a named bundle of agent configuration in DeepSeek Harness, covering model, tools and persona. Creating a session requires resolving one; failure surfaces as agent-preset/not-found.— https://github.com/deepseek-ai/deepseek-harness/discussions/10099
pending
pending is a Cordis plugin state meaning inject dependencies are unmet. Unlike failed, pending does not block the host from starting, so it often appears as a working app with one missing capability.— https://github.com/deepseek-ai/deepseek-harness/discussions/10099

Sources