Update: July 26, 2019
This section of the forum is no longer actively monitored. We are working on a support migration plan that we will share here shortly. Apologies for this inconvenience.

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.