Skip to content

fix(coding-agent): avoid recursive render tail hashing - #782

Open
achieve0410 wants to merge 4 commits into
code-yeongyu:mainfrom
achieve0410:fix/render-signature-stack-overflow
Open

fix(coding-agent): avoid recursive render tail hashing#782
achieve0410 wants to merge 4 commits into
code-yeongyu:mainfrom
achieve0410:fix/render-signature-stack-overflow

Conversation

@achieve0410

@achieve0410 achieve0410 commented Aug 10, 2026

Copy link
Copy Markdown

Summary

  • hash omitted array items and sorted object entries iteratively instead of recursively re-summarizing sliced tails
  • preserve the previous synthetic-tail depth budget, shared ancestor tracking, sparse-hole semantics, and omitted-value cache invalidation
  • add regressions for a 160,000-item array, array/object tail mutations, sparse holes, circular references, and depth-boundary cache correctness

Root cause

hashSignatureValue() restarted summarizeSignatureValue() with a fresh depth and WeakSet for each omitted tail. Arrays larger than the 40-item signature limit therefore removed only 40 entries per recursive call, making stack depth proportional to the number of omitted items and repeatedly copying smaller tails.

A 160,000-item array reproduced the reported error on Node 26:

RangeError: Maximum call stack size exceeded
    at summarizeSignatureValue (.../render-signature.js:42:33)
    at .../render-signature.js:77:35
    at Array.map (<anonymous>)

Fix

The omitted portions now feed framed [key, summarizedValue] entries into the existing FNV-1a state in one pass. Omitted values retain the former synthetic-tail depth of 1 while sharing the parent WeakSet, so the wide-value stack overflow is removed without weakening deep-tail cache invalidation or cycle handling.

Verification

  • npx vitest run test/render-signature.test.ts test/assistant-message-render-signature.test.ts test/tool-execution-render-signature.test.ts — 3 files, 14 tests passed
  • npm run check — passed, including Biome, pinned dependencies, import checks, lock checks, TypeScript, and browser smoke
  • npm run build — passed
  • source driver with 160,000 items — no overflow and final omitted-item mutation changed the signature
  • senpi-qa TUI smoke — 5/5 passed
  • senpi-qa CLI smoke — 8/8 passed, including help and unknown-option handling
  • real CLI mock-provider tool loop — 4/4 passed
  • changelog gate against upstream/main — passed

The full coding-agent suite completed 7,007 tests successfully with 35 skipped. Four unrelated existing XML recovery wire assertions failed because their broad authorization regex matched ambient repository security instructions in the provider body; this PR does not touch those tests or their support modules.


Summary by cubic

Fixes stack overflows in coding-agent interactive render signature hashing by iterating over omitted array items and truncated object keys with an FNV-1a accumulator. Preserves cache invalidation, depth limits, sparse-hole semantics, and cycle handling.

  • Bug Fixes
    • Hash omitted array tails and truncated object keys iteratively with FNV-1a, avoiding recursive tail re-summarization.
    • Preserve omitted-value depth budget (1), shared WeakSet ancestor tracking, and distinct hole vs undefined behavior.

Written for commit a2285fe. Summary will update on new commits.

Review in cubic

…e-stack-overflow

# Conflicts:
#	packages/coding-agent/CHANGELOG.md
…e-stack-overflow

# Conflicts:
#	packages/coding-agent/CHANGELOG.md
…e-stack-overflow

# Conflicts:
#	packages/coding-agent/CHANGELOG.md
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