Holiday Notice:
The Frontline Support team will be offline February 18 for President's Day but will be back February 19th. Thank you for your patience as we get to all of your questions!

Variable does not reference any declaration

I have a task:

task CleanReads {
String SampleName
File Read1
File Read2
Int Cores = 4

output {
    File CleanedRead1 = "${SampleName}_R1.fastq.gz"
    File CleanedRead2 = "${SampleName}_R2.fastq.gz"
}

runtime {
    cores: Cores
}

command {
    module load AdapterRemoval/2.2.1-foss-2016b

    AdapterRemoval \
        --file1 ${Read1} \
        --file2 ${Read2} \
        --output1 ${CleanedRead1} \
        --output2 ${CleanedRead2} \
        --trimns \
        --trimqualities \
        --gzip \
        --threads ${Cores}

}
}

I am calling the task:

    call CleanReads {
        input:
            SampleName = SampleRow[0],
            Read1 = SampleRow[6],
            Read2 = SampleRow[8]
    }

However when I run wdltool I get the following error:

ERROR: Variable CleanedRead1 does not reference any declaration in the task (line 194, col 16):

        --output1 ${CleanedRead1} \
           ^

Task defined here (line 173, col 6):

task CleanReads {
^ERROR: Variable CleanedRead1 does not reference any declaration in the task (line 194, col 16):

        --output1 ${CleanedRead1} \
           ^

Task defined here (line 173, col 6):

task CleanReads {
^

I am setting the variable CleanedRead1 in the output{}.
This is being set before I run command{}

So i am not clear why it is being flagged as an error.

Tagged:

Answers

  • lleonard188lleonard188 Member
    edited January 15

    I'm not a member of the Cromwell + WDL team, but it could be that CleanedRead1 and CleanedRead2 are inputs even if the options are called output1 and output2.

    Post edited by lleonard188 on
  • ChrisLChrisL Cambridge, MAMember, Broadie, Moderator, Dev admin

    The problem is that CleanedRead1 is a File output and therefore not evaluated until after the command finishes (so you can't use it as part of the command!)

    What you probably want to do is make a String value declaring the name of the value, then use that to decide where to write to, and where to pick up the output from, something like:

    task CleanReads {
      String SampleName
      File Read1
      File Read2
      Int Cores = 4
    
      String CleanedRead1_filename = "${SampleName}_R1.fastq.gz"
      String CleanedRead2_filename = "${SampleName}_R2.fastq.gz"
    
      output {
          File CleanedRead1 = CleanedRead1_filename
          File CleanedRead2 = CleanedRead2_filename
      }
    
      runtime {
          cores: Cores
      }
    
      command {
        module load AdapterRemoval/2.2.1-foss-2016b
    
        AdapterRemoval \
            --file1 ${Read1} \
            --file2 ${Read2} \
            --output1 ${CleanedRead1_filename} \
            --output2 ${CleanedRead2_filename} \
            --trimns \
            --trimqualities \
            --gzip \
            --threads ${Cores}
      }
    }
    
  • rick_tearlerick_tearle AdelaideMember

    Ahhhh, that makes sense.
    Will implement that.
    Can the string be called CleanedRead1 and the output file also be called CleanedRead1?
    I don't like creating extraneous variables if they can be avoided.

  • ChrisLChrisL Cambridge, MAMember, Broadie, Moderator, Dev admin

    Unfortunately, I don't think so - you'd end up with a naming collision if you tried that, and the values would have different types in any case (one a String, one an output File)

Sign In or Register to comment.