Skip to content

fix(fix): propagate Coana discovery failures + consume structured discovery result - #1444

Open
Martin Torp (mtorp) wants to merge 5 commits into
v1.xfrom
fix/fix-discovery-silent-noop
Open

fix(fix): propagate Coana discovery failures + consume structured discovery result#1444
Martin Torp (mtorp) wants to merge 5 commits into
v1.xfrom
fix/fix-discovery-silent-noop

Conversation

@mtorp

@mtorp Martin Torp (mtorp) commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Problem

socket fix silently reported success when its GHSA discovery step failed. discoverGhsaIds collapsed every failure mode to an empty list:

  • Coana exiting non-zero (the error message was discarded)
  • npx/pnpm dlx failing to fetch @coana-tech/cli
  • empty stdout from Coana
  • a non-JSON final stdout line (swallowed by a bare catch {})

An empty id list then short-circuited coanaFix with ok: true, which outputFixResult renders as "Finished!" with exit code 0. A broken Coana in a customer's CI was indistinguishable from "nothing to fix" — and because the fix E2E tests only dump CLI output on non-zero exit, a silent no-op produced zero diagnostics (the flaky Python E2E test that exits 0 yet upgrades nothing).

A second, subtler hole: "backend resolved zero artifacts" and "genuinely nothing to fix" both surfaced as an empty list, with no way to tell them apart.

Changes (5 commits)

1. fix(fix): propagate Coana discovery failures instead of reporting success

discoverGhsaIds returns CResult<string[]>: a failed Coana spawn propagates its CResult as-is (exit code and stderr intact via buildDlxErrorResult); empty stdout, a non-JSON final line, or wrongly-shaped JSON each fail with a specific message. A genuine empty result still exits 0. Both call sites (local and CI/PR mode) propagate the failure, so the real reason reaches the user with a non-zero exit — and the E2E exit-code assertion failure now dumps CLI output, making the next occurrence self-diagnosing.

2. feat(fix): consume Coana's structured discovery result + 3. bump @coana-tech/cli to 15.9.7

coana-tech/coana-package-manager#2327 (released as coana 15.9.7) adds find-vulnerabilities --output-file <file>, writing a structured result:

{ "ghsaIds": ["GHSA-..."], "artifactCount": 137, "filteredArtifactCount": 42 }

Since the Coana version is pinned in this repo, discovery now always uses --output-file and reads that file — the brittle "JSON array on the final stdout line" parsing is gone entirely. A missing, unparseable, or wrongly-shaped result file fails the run with a specific message.

The artifact counts also close the second hole: when the backend resolved 0 artifacts, an empty result is almost certainly a server-side resolve problem rather than "nothing to fix", so the CLI now warns (The Socket backend resolved 0 artifacts…) instead of only printing "Finished!".

4. fix(fix): plug discovery result edge cases (Cursor Bugbot)

readStructuredDiscoveryResult no longer throws a TypeError on non-object JSON bodies (null, arrays, scalars) — they return the intended ok: false. The --output-file temp path is now also removed when the spawn fails (previously only cleaned up on success).

5. test(fix): log CLI output on any e2e failure, not just non-zero exits

A silent no-op exits 0, so the if (code !== 0) guard hid all CLI output for exactly the failure class that is hardest to diagnose. The E2E catch blocks now log unconditionally, so the next flake occurrence shows what Coana and the backend actually reported — including the zero-artifact warning.

Compatibility

  • Coana 15.9.7 keeps the stdout output unchanged, but this CLI no longer consumes it. Users overriding --coana-version to something older than 15.9.7 will get a loud unknown option '--output-file' failure (propagated by commit 1) instead of a silent no-op — acceptable since the version is pinned.
  • Failure contract unchanged: Coana prints errors to stderr and exits non-zero; spawnCoanaDlx maps that to ok: false, which now propagates.

Tests

handle-fix-limit.test.mts: 24 tests, all passing; tsgo/oxlint/eslint clean. Discovery mocks now write the structured envelope the way coana 15.9.7 does.

  • Failure propagation: spawn failure (local + PR mode).
  • Structured result: envelope read + counts; missing file / invalid JSON / wrong shape (incl. non-object bodies) each fail with specific messages; temp file removed on spawn failure; zero-artifact warning emitted; genuine empty result still exits 0 (regression guard).
  • Verified the published @coana-tech/cli@15.9.7 exposes -o, --output-file (find-vulnerabilities --help).

Behavior change (intended)

Automation parsing socket fix --json that relied on ok: true + empty ghsaDetails when Coana was broken now gets ok: false + message and a non-zero exit.


Note

Medium Risk
Changes socket fix success/failure semantics and JSON ok for discovery errors, which can break automation that treated failed Coana runs as success; core fix path behavior is otherwise localized to discovery.

Overview
socket fix no longer treats a broken vulnerability-discovery step as “nothing to fix.” Discovery failures (Coana non-zero exit, missing/unreadable --output-file JSON) now return ok: false with a non-zero exit instead of Finished! with an empty result.

Discovery always runs Coana find-vulnerabilities with --output-file (Coana 15.9.7) and reads ghsaIds plus artifactCount from that JSON, replacing parsing the last stdout line. When artifactCount is 0, the CLI warns that backend resolve may be incomplete rather than only showing an empty list.

@coana-tech/cli is bumped to 15.9.7 (version 1.1.150). Tests mock the structured envelope and cover failure propagation and invalid discovery output.

Reviewed by Cursor Bugbot for commit 645d428. Configure here.

@mtorp
Martin Torp (mtorp) force-pushed the fix/fix-discovery-silent-noop branch from 812e9da to e07ef51 Compare July 29, 2026 09:00
@mtorp Martin Torp (mtorp) changed the title fix(fix): propagate Coana discovery failures instead of reporting success fix(fix): propagate Coana discovery failures + consume structured discovery result Jul 29, 2026
…cess

socket fix silently exited 0 with "Finished!" whenever the GHSA
discovery step failed, because discoverGhsaIds collapsed every failure
mode — Coana exiting non-zero, the dlx launcher failing to fetch
@coana-tech/cli, empty stdout, or an unparseable final line — to an
empty GHSA list, indistinguishable from "nothing to fix".

discoverGhsaIds now returns CResult<string[]>: a failed Coana spawn
propagates its error (exit code and stderr intact), and empty,
non-JSON, or wrongly-shaped output fails with a specific message. A
genuine empty array still exits 0. Both call sites (local and CI/PR
mode) propagate the failure so outputFixResult sets a non-zero exit
code and the real reason reaches the user.
Coana 15.9.7 adds `find-vulnerabilities --output-file`, writing a
structured JSON result ({ ghsaIds, artifactCount, filteredArtifactCount })
that replaces the brittle "JSON array on the final stdout line" contract
(coana-tech/coana-package-manager#2327).

discoverGhsaIds now prefers that file when the resolved Coana version
supports it (or when using a local Coana build), falling back to strict
stdout parsing for older versions. A missing, unparseable, or wrongly
shaped result file fails the run with a specific message instead of
silently skipping fixes.

The artifact counts also close the remaining diagnostic hole: when the
backend resolved 0 artifacts, an empty result is almost certainly a
server-side resolve problem rather than "nothing to fix", so the CLI
now warns instead of only printing "Finished!".
The pinned @coana-tech/cli is now 15.9.7, which always supports
`find-vulnerabilities --output-file`, so the Coana version is known at
build time and no backward compatibility is needed: drop the version
gate and the stdout final-line parsing fallback. Discovery now always
passes --output-file and reads the structured result; a missing,
unparseable, or wrongly shaped result file fails the run with a
specific message.
@mtorp
Martin Torp (mtorp) force-pushed the fix/fix-discovery-silent-noop branch from a52d44a to 645d428 Compare July 29, 2026 12:20
@mtorp
Martin Torp (mtorp) marked this pull request as ready for review July 29, 2026 12:51

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issues.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 645d428. Configure here.

Comment thread src/commands/fix/coana-fix.mts
Comment thread src/commands/fix/coana-fix.mts
Guard readStructuredDiscoveryResult against non-object JSON bodies
(null, arrays, scalars): destructuring null threw a TypeError instead
of the intended ok:false result. Also delete the --output-file temp
path when the Coana spawn fails — cleanup previously only ran on the
success path.
A silent no-op exits 0, so the `if (code !== 0)` guard hid all CLI
output for exactly the failure class that is hardest to diagnose (e.g.
discovery returning an empty id list). The catch block now logs
unconditionally, so the next occurrence shows what Coana and the
backend actually reported — including the zero-artifact warning.
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.

2 participants