This is a test version of Biostars. For the public version, visit https://www.biostars.org.
[HELP] AMR++ Host and Contaminant Removal, ERROR running $BWA mem

Hello, I've been struggling to troubleshoot this on my own and I am an absolute newbie to command line in bioinformatics. I wanted to try running the genome of b. velezensis through AMR++ to screen for ARGs but every step of the tutorial has been a wall of red text.

I already made the conda environment, when I checked the versions of each tool, each one was identified by my terminal. I already tried adding the folder to bwa.nf to my path via:

export PATH=$PATH:/path/to/your/folder

Here are my tools:

N E X T F L O W
  version 26.04.6 build 12646
  created 09-07-2026
  cite doi:10.1038/nbt.3820
  http://nextflow.io

Program: bwa (alignment via Burrows-Wheeler transformation)
Version: 0.7.19-r1273

samtools 1.24

trimmomatic -version
0.40

Here is the code I ran:

nextflow run main_AMR++.nf \
-profile local \
--pipeline rm_host \       
--reads "AMR++_results/QC_trimming/Paired/SRR30344499_R.{1,2}P.fastq.gz " \ 
--host /Users/usrnm/bin/AMRplusplus/data/host/SRR30344499.fasta  \                     
--output AMR++_results  

It was able to successfully create a BWA index, I have a folder named Alignment in my AMR++ Results folder. But afterwards I got a red wall of text:

*# starts here*

    ERROR ~ Error executing process > 'FASTQ_RM_HOST_WF:bwa_rm_contaminant_fq (SRR30344499_R)'

Caused by:
  Process `FASTQ_RM_HOST_WF:bwa_rm_contaminant_fq (SRR30344499_R)` terminated with an error exit status (1)


Command executed:

  $BWA mem SRR30344499.fasta SRR30344499_R.1P.fastq.gz SRR30344499_R.2P.fastq.gz -t 4 > SRR30344499_R.host.sam
  $SAMTOOLS view -bS SRR30344499_R.host.sam | $SAMTOOLS sort -@ 4 -o SRR30344499_R.host.sorted.bam
  rm SRR30344499_R.host.sam
  $SAMTOOLS index SRR30344499_R.host.sorted.bam && $SAMTOOLS idxstats SRR30344499_R.host.sorted.bam > SRR30344499_R.samtools.idxstats
  $SAMTOOLS view -h -f 12 -b SRR30344499_R.host.sorted.bam -o SRR30344499_R.host.sorted.removed.bam
  $SAMTOOLS sort -n -@ 4 SRR30344499_R.host.sorted.removed.bam -o SRR30344499_R.host.resorted.removed.bam
  $SAMTOOLS         fastq -@ 4 -c 6        SRR30344499_R.host.resorted.removed.bam       -1 SRR30344499_R.non.host.R1.fastq.gz       -2 SRR30344499_R.non.host.R2.fastq.gz       -0 /dev/null -s /dev/null -n

  rm *.bam

Command exit status:
  1

Command output:
  (empty)

Command error:
         -W INT        discard a chain if seeded bases shorter than INT [0]
         -m INT        perform at most INT rounds of mate rescues for each read [50]
         -S            skip mate rescue
         -P            skip pairing; mate rescue performed unless -S also in use

  Scoring options:

         -A INT        score for a sequence match, which scales options -TdBOELU unless overridden [1
         -B INT        penalty for a mismatch [4]
         -O INT[,INT]  gap open penalties for deletions and insertions [6,6]
         -E INT[,INT]  gap extension penalty; a gap of size k cost '{-O} + {-E}*k' [1,1]
         -L INT[,INT]  penalty for 5'- and 3'-end clipping [5,5]
         -U INT        penalty for an unpaired read pair [17]

         -x STR        read type. Setting -x changes multiple parameters unless overridden [null]
                       pacbio: -k17 -W40 -r10 -A1 -B1 -O1 -E1 -L0  (PacBio reads to ref)
                       ont2d: -k14 -W20 -r10 -A1 -B1 -O1 -E1 -L0  (Oxford Nanopore 2D-reads to ref)
                       intractg: -B9 -O16 -L5  (intra-species contigs to ref)

  Input/output options:

         -p            smart pairing (ignoring in2.fq)
         -R STR        read group header line such as '@RG\tID:foo\tSM:bar' [null]
         -H STR/FILE   insert STR to header if it starts with @; or insert lines in FILE [null]
         -o FILE       sam file to output results to [stdout]
         -j            treat ALT contigs as part of the primary assembly (i.e. ignore <idxbase>.alt file)
         -5            for split alignment, take the alignment with the smallest query (not genomic) coordinate as primary
         -q            don't modify mapQ of supplementary alignments
         -K INT        process INT input bases in each batch regardless of nThreads (for reproducibility) []

         -v INT        verbosity level: 1=error, 2=warning, 3=message, 4+=debugging [3]
         -T INT        minimum score to output [30]
         -h INT[,INT]  if there are <INT hits with score >80.00% of the max score, output all in XA [5,200]
                       A second value may be given for alternate sequences.
         -z FLOAT      The fraction of the max score to use with -h [0.800000].
                       specify the mean, standard deviation (10% of the mean if absent), max

*# ends here*

When I try to run the code from the executed commands it says:

zsh: command not found: mem
sort: invalid option -- '@'
Try 'sort --help' for more information.

If someone could just point out what I did wrong, or what I could do to troubleshoot it to finally reach resistome analysis I would be so grateful. Thanks!

commandlineinterface amrplusplus bwa resistome

3 answers

Two separate things are going on here, and mixing them up is likely what's confusing you.

  1. The "command not found: mem" you get when running the command yourself is expected, and not the real bug. $BWA is a Nextflow environment variable, defined only inside the pipeline's execution (from the env { BWA = "bwa" ... } block in params.config). It only exists while Nextflow is running a process. If you copy a line like $BWA mem ... straight from the error report into your own terminal, $BWA is empty there, so your shell reads it as mem SRR30344499.fasta ... — and since there's no program called mem, zsh says "command not found: mem". That's your terminal, not the pipeline.

  2. The actual pipeline error is that bwa mem itself ran and printed its own usage/options help (the long block starting with "-W INT ...") — that's bwa telling you it was called incorrectly, not a Nextflow problem. The real one-line reason is almost always in the first couple of lines of that same "Command error" block, right before the options text (often something like [E::main_mem] fail to locate the index files) — it looks like those first lines got cut off when you copied it here.

Could you paste the full .command.err from that task's work directory (the "Work dir:" path printed just above the error, something like work/fc/xxxxxx)? That will have the actual reason bwa refused to run — most likely the index files it's being given don't match the reference you used to build the index in the first step.

most probably in

$BWA mem SRR30344499.fasta SRR30344499_R.1P.fastq.gz SRR30344499_R.2P.fastq.gz -t (...)

the variable ${BWA} is not defined and is resolved to a empty string. That's why you get an error:

command not found: mem

How to fix ? use conda, or use module , try to export BWA=/path/to/bwa before running the nextflow, or define a process in your nextflow the following way

process TOTO {
(...)
script:
def BWA=task.ext.bwa?:"bwa"
"""
${BWA} mem (...)
"""

}

and in the nextflow.config

process {
withName:"TOTO" {
   ext.BWA="/full/path/to/bwa"
   }
}

Hello! I am unfamiliar with the process TOTO being described here?

For context I am on a mac, and I use terminal to input command-line. If there's a website or a video with a tutorial you could point me to I'll try running through it and see if it fixes the issue.

I have miniconda downloaded, and I use a local conda environment for AMR++ rather than module.

I tried export BWA=/path/to/bwa but it still showed the same error.

Thank you for the link, will definitely try it out (though it might be a few hours before I get back to troubleshooting due to how late it's become on my end). Also, no problem! I know I'm an absolute beginner here, I dragged and dropped the bwa executable to input the real path.

I tried doing it after running the conda environment for AMR++ and before running nextflow.

Follow-up: I think this can be pinned down without the .command.err after all, and it corrects what I said above about the index files.

Look at the command Nextflow actually ran:

$BWA mem SRR30344499.fasta SRR30344499_R.1P.fastq.gz SRR30344499_R.2P.fastq.gz -t 4 > SRR30344499_R.host.sam

The -t 4 comes after the three positional arguments. On macOS that is the whole problem.

bwa mem parses its options with the system getopt. GNU getopt, on Linux, reorders argv, so an option placed after the positional arguments is still picked up. BSD getopt, which is what macOS uses, does not: it stops at the first non-option argument. So on your Mac, -t and 4 are never parsed as an option at all. They are counted as two extra positional arguments.

bwa mem therefore sees five positional arguments, and the check in fastmap.c is:

if (optind + 1 >= argc || optind + 3 < argc) { ...usage...; return 1; }

More than three positional arguments and it prints its whole options list and exits 1. That is exactly what you got: the usage block, exit status 1, empty stdout. Nothing was cut off when you pasted it either. There is no [E::main_mem] line to find, because bwa never got as far as opening the index.

A one-line check, run from the Work dir: path printed just above the error:

bwa mem -t 4 SRR30344499.fasta SRR30344499_R.1P.fastq.gz SRR30344499_R.2P.fastq.gz > /dev/null

If that runs with the option before the files, while the original ordering prints the usage text, that confirms it.

The same difference explains the other message you saw. sort: invalid option -- '@' is the BSD sort that ships with macOS, which has no -@ flag. You got it because $SAMTOOLS was empty in your own shell, so $SAMTOOLS sort -@ 4 became plain sort -@ 4.

Two ways round it. -t is hardcoded after the inputs in modules/Alignment/bwa.nf, so either run the pipeline in its Docker or Singularity container, where the Linux userland and GNU getopt make the ordering stop mattering, or edit that line so -t ${threads} comes before the reference.

One more thing, and it may matter more than the bug itself. You said you are screening a B. velezensis genome for ARGs. --pipeline rm_host removes host contamination, which is meant for host-associated samples; a bacterial isolate has no host to remove. And the file you are passing as --host, SRR30344499.fasta, looks like it comes from the same accession as your reads, so that step would be aligning your reads against themselves. You can most likely skip host removal altogether and go straight to the resistome pipeline. The --pipeline options are listed in the AMR++ README.

Log in to answer this question.