Skip to content

fix(cli): stop compact list projection from mangling short fields - #145

Merged
ysyneu merged 1 commit into
mainfrom
fix/alert-event-list-projection
Aug 12, 2026
Merged

fix(cli): stop compact list projection from mangling short fields#145
ysyneu merged 1 commit into
mainfrom
fix/alert-event-list-projection

Conversation

@ysyneu

@ysyneu ysyneu commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Problem

The default compact projection used by `alert-event list`, `incident list`, and `incident similar` (in json/toon mode, when `--fields` is omitted) computed a single per-field byte cap by dividing the total budget by the total count of string values across every row, then geometrically halved that cap whenever the aggregate output still overflowed 16 KiB.

Each halving re-applied the shrinking cap to every string field on every row, including fields that were never responsible for the overflow (e.g. Mongo ObjectID-shaped ids, or short enum-like severity/status strings), clipping them down toward a 1-byte cap even though a single long field (typically the title) was the actual cause.

Once the cap dropped to 3 bytes or below, the truncation helper had no room left for its "..." marker and fell back to returning raw, unmarked bytes — making a shortened value indistinguishable from a genuinely short one. Piping such output to jq/grep for an exact id or status match then silently returns no hits, with no indication the field was ever truncated.

Fix

Replace the per-field cap computation with a search for the largest single cap that lets the whole page fit, then apply it once:

  • A field already shorter than that cap is left completely untouched, so only the field(s) actually responsible for the overflow get shortened.
  • The cap is never allowed to drop low enough to lose the "..." marker.
  • When no such cap exists, the command now fails with an actionable error instead of emitting values that look real but aren't.

alert-event list, incident list, and incident similar all share this helper (boundProjectedList in internal/cli/fieldproject.go), so the fix applies to all three. alert list is unaffected — it doesn't run through this default compact-projection path.

Tests

  • A fixture with long ids and a minority of oversized multi-word/CJK titles confirms the ids and short titles stay intact in both json and toon output, while only the oversized titles are marked-truncated.
  • A --fields path test confirms explicit field selection is unaffected.
  • A low-level test forces every string field to shrink under extreme pressure and asserts the "..." marker is never dropped.

`go vet ./...`, `gofmt -s -l`, `make lint` (0 issues), and `go test ./...` all pass.

The default compact projection used by alert-event list, incident list,
and incident similar (in json/toon mode, when --fields is omitted)
computed a single per-field byte cap by dividing the total budget by
the total count of string values across every row, then geometrically
halved that cap whenever the aggregate output still overflowed 16 KiB.
Each halving re-applied the shrinking cap to every string field on
every row, including fields that were never responsible for the
overflow (e.g. Mongo ObjectID-shaped ids, or short enum-like severity/
status strings), clipping them down toward a 1-byte cap even though a
single long field (typically the title) was the actual cause.

Once the cap dropped to 3 bytes or below, the truncation helper had no
room left for its "..." marker and fell back to returning raw,
unmarked bytes — making a shortened value indistinguishable from a
genuinely short one. Piping such output to jq/grep for an exact id or
status match then silently returns no hits, with no indication that
the field was ever truncated.

Replace the per-field cap computation with a search for the largest
single cap that lets the whole page fit, then apply it once. A field
already shorter than that cap is left completely untouched, so only
the field(s) actually responsible for the overflow get shortened, and
the cap is never allowed to drop low enough to lose the "..." marker.
When no such cap exists, the command now fails with an actionable
error instead of emitting values that look real but aren't.

Add regression coverage: a fixture with long ids and a minority of
oversized multi-word/CJK titles confirms the ids and short titles stay
intact in both json and toon output while only the oversized titles
are marked-truncated; a --fields path test confirms explicit field
selection is unaffected; and a low-level test forces every string
field to shrink and asserts the "..." marker is never dropped.
@ysyneu
ysyneu merged commit 1563d09 into main Aug 12, 2026
12 checks passed
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