Skip to content

scan --mode agent --json and get --json overwrite a locally modified npm file without the documented content_mismatch_overwritten warning (not in the JSON, not on stderr) #1004

Description

[agent] Found by the scheduled npm bug-hunt routine (ledger #302).

Summary

When an installed file matches neither the patch's beforeHash nor its afterHash (for example a local edit, a patch-package patch, or an npm patch change), the default mismatch policy overwrites it with the full patched content. CLI_CONTRACT says that overwrite is always surfaced, as a content_mismatch_overwritten stderr warning plus a skipped event.

apply --json and the human scan --mode agent do surface it. But scan --mode agent --json and get --json run the same in-place apply and report nothing: the JSON has no content_mismatch_overwritten record anywhere, stderr has no warning, and the exit code is 0. The patch shows as "action": "added", failed: 0, applied: 1. The local change is gone.

#955 (#424) made these envelopes report apply failures. The nested apply's warnings are still dropped.

Impact

  • --json is the automation path (CI bots, Socket integrations). Through it, socket-patch silently destroys a project's own modifications to a dependency. Under the documented policy that overwrite is allowed, but only with a warning, so the user can notice and switch to --strict.
  • In npm projects this hits real setups: patch-package / npm patch users whose patched file the Socket patch also touches lose their patch, and nothing in the JSON says so. A bot can't tell this apart from a clean apply.

Repro (Linux, main 859a279, local mock patch API serving one patch for left-pad@1.3.0)

mkdir p && cd p
echo '{"name":"p","version":"1.0.0","private":true,"dependencies":{"left-pad":"1.3.0"}}' > package.json
npm i
echo '// local edit' >> node_modules/left-pad/index.js

socket-patch scan --mode agent --json --yes <api flags> 2>err.txt >out.json; echo $?   # 0
grep -c content_mismatch_overwritten out.json     # 0
grep -c 'did not match' err.txt                   # 0
grep -c 'local edit' node_modules/left-pad/index.js   # 0: the edit was overwritten

# control 1: same state, human output
socket-patch scan --mode agent --yes <api flags>
#   Warning: pkg:npm/left-pad@1.3.0 package/index.js did not match the patch's expected original content;
#   applied the full verified patched content instead (pass --strict to fail on mismatches)

# control 2: same state, standalone apply --json
socket-patch apply --json
#   events: [{action: applied, ...}, {action: skipped, errorCode: content_mismatch_overwritten, reason: "package/index.js did not match ..."}]

# control 3: --strict works through scan --json (#955)
socket-patch scan --mode agent --strict --json --yes <api flags>   # exit 1, apply.patches[0] = {action: failed, errorCode: apply_failed, ...}

get <uuid> --mode agent --json behaves the same as scan --mode agent --json.

Expected vs actual

  • Expected (CLI_CONTRACT.md, "Global arguments", --strict note): "The --strict mismatch policy applies to the in-place apply paths (apply/get/scan --apply/hook/go redirect). DEFAULT: a file whose on-disk content matches neither the patch's beforeHash nor its afterHash is overwritten … and surfaced as a content_mismatch_overwritten stderr warning + Skipped event." The error-code table lists content_mismatch_overwritten as a skipped (warning) event. So scan --json / get --json should carry it, for example as a skipped / warning record next to the patch record in apply.patches[] / patches[], the same way Fix scan/get --json dropping apply failures (#424) #955 folds failures in, or at least print the stderr line.
  • Actual: neither. Exit 0, the patch record reads added, and nothing mentions the overwrite.

Matrix (Linux)

socket-patch npm (Node) command exit JSON warning stderr warning local edit kept
main 859a279 10.9.4 (22) scan --mode agent --json (x2) 0 no no no (overwritten)
main 859a279 10.9.4 (22) get <uuid> --mode agent --json 0 no no no
main 859a279 12.2.0 (24) scan --mode agent --json (x2) 0 no no no
main 859a279 12.2.0 (24) get <uuid> --mode agent --json 0 no no no
main 859a279 10.9.4 scan --mode agent (human) 0 n/a yes no
main 859a279 10.9.4 apply --json 0 yes (skipped event) n/a no
v4.0.0 10.9.4 get <uuid> --json 0 no no no

Not a regression: v4.0.0 get --json drops the warning too. The logic doesn't depend on the OS (no npm process is involved in the apply), so I didn't run a macOS / Windows probe.

Suspect code

  • crates/socket-patch-cli/src/commands/get.rs:2288-2297 (nested_apply_args): the nested apply runs with json: false and silent: quiet, so for a JSON caller warn_mismatch_overwrites returns early (crates/socket-patch-cli/src/commands/apply.rs:55-58). The apply's own JSON envelope, which records the content_mismatch_overwritten event (apply.rs:1264-1272), is never built.
  • crates/socket-patch-cli/src/commands/apply.rs:987 (ApplyRunReport) carries only failures / run_error back to the caller. There's no field for the mismatch-overwrite warnings, so fold_apply_failures (get.rs, Fix scan/get --json dropping apply failures (#424) #955) has nothing to fold into the scan / get envelope.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions