Fail-fast tool batches for DeepSeek Harness: inside a step, concurrency-safe calls still overlap, but after the first failed call every remaining unstarted call is denied before dispatch and returned to the model as a synthesized `is_error` "not executed" result.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-fail-fast
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:x402/dsh-fail-fast
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
中文 | English
A DeepSeek Harness (DSH) plugin that adds fail-fast behavior to tool calls within a
single step. Once any tool call fails, the plugin intercepts all remaining unstarted
calls and returns synthesized is_error: true ("not executed") results to the model.
Models frequently emit dependent tool calls in a single response (e.g., write
followed by bash). DSH's agent loop already handles execution order:
concurrency-safe reads share parallel groups, while other calls run sequentially in
their own ordering groups according to model output order. The missing piece is
failure handling — when an earlier call fails, DSH still dispatches subsequent calls
whose preconditions no longer hold, wasting execution and risking destructive side
effects.
Models naturally emit tool calls in dependency order, making the output sequence itself an implicit dependency topology. Leveraging this property, the plugin leaves DSH's concurrency and ordering schedule intact and requires no knowledge of tool semantics or dependency graphs, simply halting unstarted calls after a failure point. Because skipped calls return with an explicit "not executed" reason, the current turn's context stays intact and the model can recover directly on the next turn.
Features
- Scheduling untouched — the plugin takes over no scheduling: concurrency-safe
calls still overlap up to
maxParallelToolCalls, other calls keep their ordering groups, and dispatch is never degraded to global serial execution. - Stop at the first failure — any final
is_error: trueresult (tool error, policy denial, timeout, post-execute block) cancels every remaining unstarted call; siblings already started in the failing group finish normally. - Model-repairable result — skipped calls come back as
is_error: truewithFailFastSkippedError/SKIPPED_AFTER_FAILUREand anError: Not executed: …message, so the model can fix the failure and re-issue the remaining calls. - Non-invasive — the plugin only observes public DSH extension points
(
session/event,tools/result,tools/pre-execute); it never replaces the tool executor or rewrites the failing call's own result, and a denied call runs no body and triggers no approval. - No dependencies, no config overrides — a single dependency-free ESM Host plugin;
cordis.patch.ymlonly inserts the plugin row and overrides nothing. - Scoped — only model-direct top-level calls participate; PTC sub-calls (which
carry
exec.parent) and subagents (separate sessions) have independent state. Single-call batches and aborted batches are unaffected.
How it works
DSH's agent loop already runs one step's calls as ordering groups, one group at a time: a group is fully drained and committed in model order before the next starts. On top of that the plugin does three things:
Batch tracking — listens to
session/event(step/start,tool/call) and records the ordered call ids of the step in flight.Failure point — listens to
tools/resultand pins the firstis_error: truecall in model order.Cancel the rest — a prepended
tools/pre-executelistener denies calls after the failure point that have not started. A denied call never runs its body and never triggers an approval, but the loop still records the normaltool/call+tool/resultpair, so the model sees:Error: Not executed: the preceding `read` call failed, so fail-fast skipped this call and every call that had not started yet in the batch. Fix the failure first, then re-issue the remaining calls in dependency order.
The failing call's own result is left untouched.
Behavior and boundaries
- Any final
is_error: trueresult counts as a failure: tool errors, policy denials, timeouts and post-execute blocks all cancel the rest of the batch. - Calls already started in the failing group run to completion (they declared themselves concurrency-safe and independent, so their results remain meaningful); no new call starts afterwards. If the failure commits very quickly, a same-group tail that has not been prepared yet is also skipped; that is the conservative direction.
- Non-concurrency-safe calls (writes, bash, …) are single-call groups, so
write → bashdependency order is preserved naturally. - A single-call batch is unaffected; batch state resets at every step boundary.
- Aborted batches are synthesized by the agent loop itself (
aborted before dispatch); this plugin stays out of that path. - Cost: already-started same-group calls cannot be recalled (they are independent,
which is what allows the overlap). Tools that want to stop earlier must honor
exec.signal.
Install
The plugin is published on npm as dsh-fail-fast. In the DSH Web Plugins page,
choose Add plugin, enter the package name, and click Enable now once it is
installed:
dsh-fail-fast
Or install it from a session with the plugin manager tool (installs and enables it):
plugin_manager(action: "install_bundle", target: "dsh-fail-fast")
DSH reports newer versions and updates the plugin in place.
Other install paths
- Pinned version / preview commit — paste
https://github.com/x402/dsh-fail-fast#<tag-or-commit>into the install field. GitHub installs needgitand GitHub connectivity, and DSH does not check them for updates, so upgrading means uninstalling and installing again. - Local development — clone the repository and install the checkout as a bundle
(
link:or an absolute path); see AGENTS.md.
The package.json declares DSH compatibility >=0.2.0-rc.2 <0.3.0. Behind a slow
network, pick a custom registry mirror in the install dialog.
plugin_manager list_plugins / list_bundles confirm the fail-fast row is
enabled.
Acknowledgements
The problem this plugin solves was originally identified by @Golden-Pigeon.
License
MIT © 2026 x402 and the dsh-fail-fast contributors
Links
More in this category
yjh051108/dsh-routing-suite★ 6994
One repository, three parts: a runtime injector for DSH plugin packages (inject, hot-reload, unload, promote a dev staging tool to the front, route self-heal, plus a settings-page plugin manager that lists, unloads and drags folders in to internalize), a task-aware reasoning-mode router agent preset (router-standard / router-spec / router-react), and a graded two-level task protocol whose six tools (commit_star, lock_stage, revise_do, edit_plan, mark_task, redteam_verdict) pin task state to disk. The injector implementation ships in-tree, so the install carries its own behaviour rather than a dependency list.
strukto-ai/mirage#dsh★ 3762
Swaps the filesystem and bash providers for a mirage virtual workspace: file tools and shell commands run over mounted resources (RAM, S3, Redis, Slack, Gmail, Notion, Postgres) instead of the host disk, with per-mount read/write/exec modes, per-command sandbox routing (monty, pyodide, quickjs in process; docker, e2b, daytona remote), and installed CLIs (git, gh, slack, linear, ntn, gws, or one you register) as head words in the virtual terminal.
first-fluke/oh-my-agent#dsh★ 1357
Runs project OMA checks before and after tool execution and when a turn tries to finish. Installs its OMA CLI dependency and initializes unconfigured projects on first use. Requires Node.js 22+; initial setup needs network access and project write access.
MichengAI/dsh-skills-manager★ 444
Manages local DeepSeek Harness skills in Settings and shows shared Agent skills as read-only.
hust-open-atom-club/oh-dsh★ 324
Community distribution: TUI, desktop, and Web UI as one bundle with layered installation.
Fishquito7/dsh-skill-mcp-panel★ 248
Manages DSH skills and MCP servers from the web settings: skill cards with hot enable/disable, workspace scopes, groups, batch migration and drag-and-drop import, plus stdio/HTTP MCP CRUD with connection tests, secret redaction and the unified dsh-panel CLI.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.