Skip to content

fix: keep closing brackets when desyncing after a complete JSON array - #305

Open
detail-app[bot] wants to merge 1 commit into
masterfrom
detail/bug-fix/fix-keep-closing-brackets-when-desyncing-after-a-c-329256
Open

detail-app[bot] wants to merge 1 commit into
masterfrom
detail/bug-fix/fix-keep-closing-brackets-when-desyncing-after-a-c-329256

Conversation

@detail-app

@detail-app detail-app Bot commented Sep 16, 2026

Copy link
Copy Markdown

Detail bug report: View on Detail

Fixes ENG-706

Bug

JsonArrayFramer defers emitting the array brackets (especially the closing ]) until finish() calls writeClose. When the .done state (the closing ] already consumed) hit trailing non-whitespace junk, it called enterDesync directly and switched to verbatim copy-through without ever writing the deferred brackets, and finish()'s empty .desync arm never recovered them. So [1]extra was emitted as [1extra and []( as (. The .done.desync path was uniquely missing bracket emission — the sibling .in_element and .expect_element_or_end desync paths both close the array via writeClose in finish().

Fix

Call writeClose(out) before enterDesync in the .done state, mirroring those sibling finish() branches. writeClose already handles both wrote_open == true (non-empty array: emits ]) and wrote_open == false (empty array: emits [ then ]), so both sub-cases are covered. One line in src/pipeline/frame_json_array.zig.

Testing

  • Regression test (added, inline in frame_json_array.zig): drives [1]extra and []( through runChunked across chunk sizes {1, 7, 4096} (the .done state carries across ingest calls, so chunk-boundary placement matters), asserting byte-preserving output of [1]extra / [](.
  • Routine checks: all pre-existing framer unit tests pass; zig build test is green (one pre-existing env-dependent S3 e2e test skipped); zig fmt --check, ziglint, and debug + ReleaseSafe builds pass; task do (format + lint + ReleaseSafe test) and task build:safe are green.
  • End-to-end: ran the edge-datadog distribution against the repo's echo-server as a capture upstream. POSTing [{"message":"hi"}], [1]extra, and []( to /api/v2/logs (the production .pipe_stream / .format = .json_array path), the upstream captured [{"message":"hi"}], [1]extra, and []( respectively — vs. the bug's [1extra / ( — confirming the fix at the wire level with no regression on valid input.
  • Not verified: task test:s3-e2e (the S3-dump MinIO e2e) could not be run here — Docker failed to pull minio/minio (registry access denied). It exercises the unrelated S3-dump extension and is independent of this change; it is also the single pre-existing skip in the normal test suite.

Automatic Fixes PRs can be configured here.

@macroscopeapp

macroscopeapp Bot commented Sep 16, 2026

Copy link
Copy Markdown

Approvability

Verdict: Approved at 4a90b5f

Macroscope's review found this PR approvable — This is a one-line JSON-array framing fix that restores deferred closing brackets before malformed trailing data is copied through, with regression coverage for chunk boundaries and empty/non-empty arrays. Existing valid-input behavior and unrelated paths are unchanged.

You can add or adjust custom eligibility rules. Learn more.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant