Skip to content

[Bug]: explainer check receipt is truncated at ~8 KiB on macOS when stdout is a pipe, so deliver/finalize fail with "Could not parse the successful artifact-check receipt" #1130

Closed

Description

@Moonhyeseong

Archify version or commit

3.2.0 (installed skill package); reproduced against main at 81c6be8.

Installation method

Claude Code skill (~/.claude/skills/archify)

Diagram type

explainer

Exact command

node bin/archify.mjs finalize explainer candidate.archify.md pricing-backdata.html --json
# and directly:
node bin/archify.mjs check pricing-backdata.html --json | wc -c

Minimal redacted JSON reproduction

Any explainer whose artifact-check receipt is larger than one pipe chunk. Mine has 7 panels and 4 native diagrams (1 architecture with 11 edges, 1 workflow, 2 erd); its full receipt is 21,289 bytes because the diagram-check section lists minimumProjectedTextPx per node and edge. A smaller explainer (receipt under 8 KiB) does not reproduce.

Validation receipt or exact error

{"code":"delivery/receipt-invalid","severity":"error",
 "message":"Could not parse the successful artifact-check receipt: Unterminated fractional number in JSON at position 8127 (line 270 column 43)"}

finalize reports gates.validate = not-run, deliver = fail. Running the checker alone with a piped stdout gives exactly 8192 bytes:

$ node archify/bin/archify.mjs check pricing-backdata.html --json | wc -c
    8192

and the output ends mid-number: "minimumProjectedTextPx": 6.75109717868.

Expected behavior

The checker prints its whole receipt and deliver/finalize pass (the artifact itself is fine: validate passes and the same HTML opens correctly).

Actual behavior

archify/scripts/check-render-output.mjs takes the explainer branch (isExplainerHtml), prints the receipt with console.log and calls process.exit() on the next line. On macOS process.stdout is asynchronous when it is a pipe, so the process exits after the first chunk and the receipt is cut. deliver spawns the checker with stdio: 'pipe', fails to JSON.parse the partial output and reports delivery/receipt-invalid. The non-explainer path at the bottom of the same script already avoids this by setting process.exitCode and letting stdout drain (the comment there says so); only the explainer branch still exits eagerly.

This is distinct from #525 / #590 (parent-side maxBuffer): here the child truncates its own output.

Environment

macOS 26.3 (Darwin 25.3.0) · Node 22 · zsh. Not reproduced on Linux, where pipe writes are synchronous.

Final checks

  • I searched existing issues for the same problem.
  • I removed access tokens, credentials, private repository contents, and personal or customer data.

I have a one-file fix ready (exit from the process.stdout.write callback and hold the module so the diagram path does not print a second receipt); I will open it as a draft PR referencing this issue.

Activity

  1. tt-a1i commented on Nov 6, 2026

    @tt-a1i
    Owner

    Stable backport is prepared in Draft PR #1240 targeting main: #1240 . It preserves @Moonhyeseong's original #1131 fix and its merged regressions, with no unrelated dev changes. On macOS, both >64 KiB piped success/failure tests reproduce truncated JSON on current main and pass with the backport; the focused checker/CLI/finalize/core tests pass (69 tests), and the extracted ZIP also passes the large receipts and dependency-free Explainer smoke. Final-head CI is now successful: https://github.com/tt-a1i/archify/actions/runs/42259786396 . Human confirmation is still pending. This is not merged or released: published stable 3.2.0 and existing installations remain unchanged.

  2. tt-a1i commented on Nov 10, 2026

    @tt-a1i
    Owner

    Thank you for the clear report and for the original fix.

    This is fixed. The explainer checker now waits until the full receipt has flushed before exiting, so a piped stdout on macOS is no longer truncated mid-JSON.

    It is on main now and will ship in the next stable release. Published v3.2.0 and current Skill installations do not include it yet. If it still happens after you update to current main, please reopen and we will take another look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions