Skip to content

fix(manifest): auto-manifest reads the Conda file it actually detected - #1562

Merged
Jeppe Fredsgaard Blaabjerg (jfblaa) merged 1 commit into
v1.xfrom
jfblaa/conda-auto-manifest-yaml
Sep 25, 2026
Merged

Jeppe Fredsgaard Blaabjerg (jfblaa) merged 1 commit into
v1.xfrom
jfblaa/conda-auto-manifest-yaml

Conversation

@jfblaa

@jfblaa Jeppe Fredsgaard Blaabjerg (jfblaa) commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

[agent] Takes over Martin Torp (@mtorp)'s draft in #1561, rebased onto v1.x after the 1.1.179 release. The code is his; I rebased, reviewed and verified it end to end.

The bug

--auto-manifest detects a Conda project by looking for either environment.yml or environment.yaml, but detectManifestActions() only returned conda: true and threw the filename away. generateAutoManifest() then read environment.yml unconditionally.

On a repo whose Conda file is environment.yaml, every run does this:

Detected an environment.yml file, running default Conda generator...
Manifest Generation Failed: The file was not found at <repo>/environment.yml

The scan still uploads, the CLI still exits 1. You get a completed scan and a failed CI job on every run, and the packages in the file's pip: block never reach the scan, because the conversion that produces them is the step that failed.

The known workaround is a socket.json with defaults.manifest.conda.infile naming the real file, which works because that override is the one path that skips the hardcoded default.

To be clear on a question that came up in triage: switching to --dynamic-sbom-inference is not a workaround. That flag only covers Gradle, sbt and Maven. Conda and Bazel are reachable only through --auto-manifest, which remains the supported flag for them and for single-root JVM facts and the reachability sidecar.

The fix

Detection reports which file it found (GeneratableManifests.condaFile) and the generator reads that one. A socket.json infile still wins when set.

Two more bugs in the same code path

The generated requirements.txt landed in the wrong directory. It was written relative to process.cwd() rather than the target dir, so socket manifest auto <dir> and socket scan create <org> <dir> dropped it outside the tree being scanned and the scan never picked it up. Invisible when you run from the repo root, which is what CI does.

Conda was the one auto-manifest ecosystem with no fail-closed check. Gradle, Maven and sbt abort the run when their generator fails (#1392); Conda just set exit 1 and carried on. That is what produces the "completed scan + failed CI job" pair, and the scan that uploads is missing the pip: packages. Conda now calls abortManifestRunIfFailed like the others.

That last one is a deliberate behavior change and the one thing worth a second opinion. Before: scan uploads, exit 1. After: the run stops before upload. It matches the policy the other ecosystems already follow, on the grounds that a partial SBOM silently under-reports dependencies. Happy to drop it if the team would rather warn and continue.

socket manifest conda on its own also falls back to .yaml now, so the two commands agree on what counts as a Conda file.

Verification

End-to-end against a real org, on a directory with an environment.yaml (with a pip: block) plus a package.json, so the scan has something else to upload — the customer's situation:

released v1.1.179 this branch
exit code 1 0
scan created yes yes
components resolved npm/lodash npm/lodash, pypi/requests, pypi/flask, pypi/certifi, pypi/charset-normalizer, pypi/idna, pypi/urllib3

So before the fix the scan uploads with every Python dependency silently missing, and CI goes red anyway. After, the full transitive PyPI tree resolves and the run is green.

Also verified: .yml repos unchanged; socket.json infile still wins; requirements.txt lands in the target dir rather than the invoking cwd; a Conda generator failure now aborts before upload; socket manifest conda works on a .yaml repo with no flags, where it previously needed --file.

The new unit tests are genuine regression tests — reverting the four source files and keeping the tests fails 7 of them, including .yaml detection and abort-on-failure.

check:tsc passes, lint passes on the changed files, src/commands/manifest 503 passed, src/commands/scan 274 passed.

Confidence

High on the two clear bugs (wrong filename, wrong output dir): small, well-tested, root cause understood, verified end to end against a real scan.

Medium on the fail-closed change, not because the code is doubtful but because it is a judgement call about behavior. It makes a currently-uploading run stop. That is right when the missing pip: block would under-report dependencies, but any team relying on the scan landing despite a broken Conda file will see a new hard failure. Consistency with Gradle/Maven/sbt argues for it; it is the piece to say no to if anyone disagrees.

One pre-existing issue I hit and deliberately left alone: a malformed Conda file produces an empty requirements.txt and exits 0, because the converter is a line scanner for the pip: block rather than a YAML parser. Out of scope here, worth its own ticket.

Release

No hand-written version bump. Entries go under ## [Unreleased] for the publish workflow to promote. The draft had hand-written a ## [1.1.179] heading; the release workflow has since written the real one, so that was dropped in the rebase.

🤖 Generated with Claude Code


Note

Medium Risk
Changes scan-create behavior when Conda manifest generation fails (upload may stop instead of completing with a partial SBOM) and touches manifest output paths used during uploads.

Overview
Fixes Conda handling in --auto-manifest and socket manifest conda so the CLI uses the environment file it actually finds, not a hardcoded environment.yml.

Detection now exposes condaFile (environment.yml or environment.yaml, preferring .yml when both exist) via findCondaFile, and auto-manifest passes that path into the generator—socket.json infile still overrides. The standalone manifest conda command uses the same fallback when --file is omitted.

Generated requirements.txt is written with path.resolve(cwd, out) so scans targeting a subdirectory pick up the file even when the CLI is invoked from elsewhere.

Conda failures now abort auto-manifest through abortManifestRunIfFailed, matching Gradle/Maven/sbt: a failed Conda step no longer continues to upload a scan missing pip: dependencies.

Reviewed by Cursor Bugbot for commit f76bf24. Configure here.

Detection accepted both environment.yml and environment.yaml but only
returned a boolean, so the filename was dropped. The generator then read
environment.yml unconditionally and failed on any repo using the .yaml
spelling, unless a socket.json infile override was in place.

Detection now reports which file it found and the generator reads that one.
socket.json still wins when it sets infile.

Two more things in the same path:

- The generated requirements.txt was written relative to the process cwd
  instead of the target dir, so `socket manifest auto <dir>` and
  `socket scan create <org> <dir>` dropped it outside the scanned tree.
  It now resolves against the target dir, which is what the --out flag
  already documents.

- Conda was the one auto-manifest ecosystem with no fail-closed check.
  Gradle, Maven and sbt abort the run when their generator fails; Conda
  just set exit 1 and carried on, so a scan uploaded without the pip block
  and the CLI still exited non-zero. Conda now aborts like the others.
@jfblaa Jeppe Fredsgaard Blaabjerg (jfblaa) changed the title [agent] fix(manifest): auto-manifest reads the Conda file it actually detected fix(manifest): auto-manifest reads the Conda file it actually detected Sep 25, 2026
@jfblaa

Copy link
Copy Markdown
Contributor Author

I am not familiar with Conda, so I am deferring to Claude on this one.

@mtorp Martin Torp (mtorp) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@jfblaa
Jeppe Fredsgaard Blaabjerg (jfblaa) merged commit 79b34a0 into v1.x Sep 25, 2026
15 of 17 checks passed
@jfblaa
Jeppe Fredsgaard Blaabjerg (jfblaa) deleted the jfblaa/conda-auto-manifest-yaml branch September 25, 2026 09:40
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