fix: apptainer command not recognized when singularity is absent #4010
Conversation
📝 WalkthroughWalkthroughThe Singularity deployment module now supports automatic detection and selection between apptainer and singularity binaries. The code prioritizes apptainer when available, otherwise falls back to singularity, setting a Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/snakemake/deployment/singularity.py (1)
220-223: Consider updating error message to reflect the detected binary.The error message says "singularity version" but
self.binarycould be"apptainer". A minor consistency improvement:Suggested fix
except subprocess.CalledProcessError as e: raise WorkflowError( - f"Failed to get singularity version:\n{e.stderr.decode()}" + f"Failed to get {self.binary} version:\n{e.stderr.decode()}" )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/snakemake/deployment/singularity.py` around lines 220 - 223, The exception message always mentions "singularity" though the code uses self.binary (which may be "apptainer"); update the WorkflowError raised in the except block (the subprocess.CalledProcessError handler) to reference self.binary dynamically and include the stderr details — i.e., change the message text from "Failed to get singularity version" to something like "Failed to get {self.binary} version" and include e.stderr.decode() as before so the error accurately names the detected binary.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/snakemake/deployment/singularity.py`:
- Around line 142-145: shellcmd() currently reads Singularity().binary without
ensuring detection; call Singularity.check() at the start of shellcmd() so the
singleton detects apptainer/singularity before using Singularity().binary
(replace the direct access with a call sequence that invokes Singularity.check()
and then reads Singularity().binary or falls back). Update any references in the
function that build cmd (the envvars/binary usage) to use the post-check value;
note Image.pull() already calls check() but shellcmd() must be self-sufficient
by invoking Singularity.check() itself.
---
Nitpick comments:
In `@src/snakemake/deployment/singularity.py`:
- Around line 220-223: The exception message always mentions "singularity"
though the code uses self.binary (which may be "apptainer"); update the
WorkflowError raised in the except block (the subprocess.CalledProcessError
handler) to reference self.binary dynamically and include the stderr details —
i.e., change the message text from "Failed to get singularity version" to
something like "Failed to get {self.binary} version" and include
e.stderr.decode() as before so the error accurately names the detected binary.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 318e0497-e609-4763-9e02-a973bf0c3c2b
📒 Files selected for processing (1)
src/snakemake/deployment/singularity.py
🤖 I have created a release *beep* *boop* --- ## [9.17.0](v9.16.3...v9.17.0) (2026-03-13) ### Features * Allow storing snakemake metadata in files or databases ([#4012](#4012)) ([dd75f31](dd75f31)) * Allow to specify comparison command per-unit test ([#3956](#3956)) ([b88171c](b88171c)) * job table orderd topological when run is started ([#4018](#4018)) ([75cf506](75cf506)) * lambda functions for priority in rules ([#3253](#3253)) ([d2aa226](d2aa226)) * Make on... directive of modules accessible ([#4050](#4050)) ([e9f2e1c](e9f2e1c)) ### Bug Fixes * adjust conda tests to not fail on apple silicon; fix [#4040](#4040) ([#4049](#4049)) ([f5b0142](f5b0142)) * allow "--containerize apptainer" to output apptainer format instead of dockerfile ([#4030](#4030)) ([f5cac30](f5cac30)) * apptainer command not recognized when singularity is absent ([#4010](#4010)) ([b8162e2](b8162e2)) * capture stderr when tests fail ([#3995](#3995)) ([97d74ba](97d74ba)) * **docs:** make Data-dependent conditional execution a complete example ([#4043](#4043)) ([3a1d7f2](3a1d7f2)) * don't build the DAG when running unlock. Fixes [#4000](#4000) and [#198](#198) ([#4007](#4007)) ([acf79fd](acf79fd)) * Ensure pixi tasks may be run as advertised ([#4046](#4046)) ([88253c2](88253c2)) * fix checkpoint handling corner cases ([#3870](#3870) and [#3559](#3559)) ([#4015](#4015)) ([63f4257](63f4257)) * issue 3642 ([#4054](#4054)) ([76e6fc2](76e6fc2)) * issue 3815 ([#4026](#4026)) ([b0eec96](b0eec96)) * logging None in shellcmd context causes error ([#4064](#4064)) ([d0652cd](d0652cd)) * lookup function returns default value for empty DataFrame queries ([#4056](#4056)) ([f71de97](f71de97)) * make `cache: omit-software` a rule specific property ([#4085](#4085)) ([034a9e7](034a9e7)) * reduce number of tests leaving temporary files behind ([#4033](#4033)) ([a3a1c97](a3a1c97)) * regression in dynamic resource handling ([#4038](#4038)) ([f2c554a](f2c554a)) * somewhat shorter announce message ([#4080](#4080)) ([57efc71](57efc71)) ### Performance Improvements * switch reretry with tenacity; decouple container classes (with Python 3.7 compat for old scripts) from rest of the codebase (enabling moving to newer python versions) ([#4032](#4032)) ([ffb19e7](ffb19e7)) ### Documentation * Add AI-assisted contributions policy to contributing guidelines ([#4051](#4051)) ([dd70526](dd70526)) * **codebase:** Update & simplify plugin architecture section ([#4052](#4052)) ([176cf63](176cf63)) * Correct workflow.source_path() description in documentation ([#4036](#4036)) ([45883c5](45883c5)) * fixed wrong code example for collect() function ([#4037](#4037)) ([5c85ed8](5c85ed8)) * Minor docs improvements ([#4089](#4089)) ([29ea226](29ea226)) * switch to sphinx_design for tabs ([#3976](#3976)) ([9674614](9674614)) * typo in the migration table breaking a pip install command ([#4024](#4024)) ([66f9dda](66f9dda)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
What does this fix?
Closes #3860
Problem
Snakemake only checks for a binary named
singularitywhen using--sdm apptainer. Users who haveapptainerinstalled (but notsingularity) get the error:"The apptainer or singularity command has to be available in order to use apptainer/singularity integration."
Solution
Updated
singularity.pyto check for bothapptainerandsingularitybinaries, preferringapptainer(the modern name). All hardcoded"singularity"references replaced with the dynamically detected binary name.Changes
snakemake/deployment/singularity.py— Detection checksapptainerfirst,then
singularity. Updatedcheck(),pull(),shellcmd(), and__init__()to use the detected binary name.QC
Summary by CodeRabbit
Release Notes