GeezerVison is showing github.com — Agent-mode `apply` can't apply Maven patch records keyed by jar member paths, although `vendor` accepts the same record · Issue #264 · SocketDev/socket-patch
Agent-mode apply can't apply Maven patch records keyed by jar member paths, although vendor accepts the same record #264Description[agent] Filed by Claude Code on behalf of Mikola Lysenko (@mikolalysenko) while adding Maven patch SBOM annotations to depscan. Repro artifacts were produced with real Maven and a stub patch API.
Summary
Maven patch records are keyed differently depending on the consumer:
- Vendored mode (
vendor, scan/get --mode vendored) treats record file keys as jar member paths (META-INF/NOTICE.txt, org/…/Foo.class). It extracts the cached jar, applies the patch to the members, and re-zips.
- Agent mode (
apply) resolves the keys relative to the version directory (~/.m2/repository/<g>/<a>/<v>/<key>) and never opens the jar.
So one API record cannot serve both modes. The Socket patch backend builds Maven patches as jar-member overlays: depscan's maven repacker applies the record's files as jar entries at the archive root. Every such patch therefore fails in agent mode.
Impact
Agent mode (scan --sync, get + apply) is unusable for real Socket Maven patches. It fails with apply_failed: … File not found, and the jar in ~/.m2 stays unpatched. The docker e2e only passes because its record uses a version-directory key (package/commons-lang3-3.12.0.pom).
Repro
Stage one record in .socket/manifest.json with a blob, keyed META-INF/NOTICE.txt (git-sha256 before/after of the member, exactly like e2e_vendor_maven_build::stage_manifest). MAVEN_REPO_LOCAL holds Central's commons-lang3 3.12.0 jar and pom.
socket-patch apply --json --offline
-> exit 1 {"status":"partialFailure","events":[{"action":"failed","errorCode":"apply_failed",
"error":"Cannot apply patch: META-INF/NOTICE.txt - File not found"}]}
~/.m2 jar: PRISTINE
socket-patch vendor --json --offline (same manifest)
-> exit 0 {"events":[{"action":"applied","files":[{"path":"META-INF/NOTICE.txt","verified":true,"appliedVia":"blob"}]}]}
Expected vs actual
- Expected: agent-mode
apply handles Maven records whose keys are not version-directory files by patching the jar's members in place. It could reuse the vendored stage_local_jar / member-apply path, rewriting the jar and its .sha1, and keeping the rollback before-blob as the original jar. Alternatively it refuses Maven member-keyed records up front with a clear code that recommends --mode hosted/vendored.
- Actual: a generic "File not found" failure.
CLI revision
3efdc31d
Suggested fix
- Share the vendored jar-member application with
apply, keyed off "the record key is not a file in the version directory, but is an entry in <a>-<v>[-<classifier>].jar".
- Add a docker/e2e case with a member-keyed record.
- Rollback and VEX (
vex_consumed maven copies) need to agree on the after-hash semantics: member hash vs. whole-jar hash.
File refs (at 3efdc31)
crates/socket-patch-core/src/patch/apply.rs (no jar/zip handling; see the classifier comment near l.350)
crates/socket-patch-core/src/vendor/maven_repo.rs:153-420 (vendor_maven: member-level apply + deterministic re-zip)
crates/socket-patch-cli/tests/docker_e2e_maven.rs:109-116 (version-dir keys only)
Activitymikolalysenko commented on Oct 6, 2026 CollaboratorAuthor More actions [agent] Janitor: closing as completed. PR #646 (merge 0685ba8c, "Full Gradle support in agent, hosted and vendored modes") added socket-patch-core/src/patch/jvm_jar.rs ("Agent-mode patches of JVM jars (#264)"). apply_maven_base (commands/apply.rs:2480) handles every pkg:maven record: jvm_jar::classify detects a member-keyed record, and apply_jar_swap replaces each consumed ~/.m2 and Gradle copy with the patch service's jar after verifying the member hashes. The original is kept in .socket/jvm-originals/ for byte-exact rollback. Offline, the record refuses with jvm_agent_service_required and writes nothing. Tests: member_record_apply_repair_rollback_is_byte_exact (tests/gradle_agent_cli.rs:1153) and gradle_agent_264_member_record_whole_jar (tests/e2e_gradle_agent_build.rs). CLI_CONTRACT.md documents it under "Agent mode". These tests use a Gradle-shaped fixture. If a pom.xml-only project still fails, reopen this with the repro.
Generated by Claude Code
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|