Skip to content

fix: prevent empty-{} loop in DUUL review tools (optional fields + file inputs)#16

Merged
Suprhimp merged 1 commit into
masterfrom
devplanningo/fix-duul-plan-arg
Jun 5, 2026
Merged

fix: prevent empty-{} loop in DUUL review tools (optional fields + file inputs)#16
Suprhimp merged 1 commit into
masterfrom
devplanningo/fix-duul-plan-arg

Conversation

@Suprhimp

@Suprhimp Suprhimp commented Jun 5, 2026

Copy link
Copy Markdown
Member

Problem

request_plan_review / request_code_review / request_execution_partition looped on MCP -32602: ... required whenever a caller emitted an empty {} argument object. Root cause:

  1. A large inline plan/code string collapses to {} when serialized into the tools' ~25-field nested schema (worse on Sonnet).
  2. The required .min(1) field made the MCP SDK reject pre-handler, so the handler's friendly retry guard was dead code → unrecoverable identical-retry loop.

Confirmed empirically across ~15 workspace transcripts (keys=[], repeated).

Fix

  • Reachable guards: relax large required fields (plan, code, approved_plan, partition workspace_root) to optional; the handler now returns actionable guidance instead of opaque -32602.
  • File escape hatch: plan_file / code_file / approved_plan_file — write big content to a file, pass a relative path; server reads it scoped + symlink-guarded.
  • Security: safePath now applies sensitive/blocked-path checks to the symlink-resolved real path too (closes in-root symlink → .env read). Regression test added.
  • Reviewer prompts emit compressed output; duul-planner switched to Opus + submits via plan_file.
  • Docs (README, README.ko, CLAUDE.md, agent) updated; changeset added.

Verification

  • tsc clean, 68/68 tests pass (8 new for resolveInlineOrFile incl. symlink-bypass).

🤖 Generated with Claude Code

… inputs

request_plan_review / request_code_review / request_execution_partition
collapsed to an empty {} when a large plan/code string was inlined, and the
MCP SDK rejected it pre-handler (-32602: required) before the recovery guard
could run — leaving callers in an unrecoverable identical-retry loop.

- Relax large required string fields (plan, code, approved_plan, partition
  workspace_root) to optional so the handler's friendly guard is reachable
- Add plan_file / code_file / approved_plan_file: write large content to a
  file and pass a relative path; server reads it scoped + symlink-guarded
- Harden safePath: apply sensitive/blocked-path checks to the symlink-resolved
  real path, not just the logical path (closes in-root symlink-to-secret read)
- Reviewer system prompts emit compressed output to save tokens
- duul-planner now runs on Opus and submits plans via plan_file
- Update README / README.ko / CLAUDE.md / agent prompt; add tests + changeset

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Suprhimp Suprhimp merged commit 7a6123f into master Jun 5, 2026
1 check passed
@Suprhimp Suprhimp deleted the devplanningo/fix-duul-plan-arg branch June 5, 2026 14:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant