Skip to content

Reference Lint Rules

Lint and validation rules ​

Run sprocket explain <RULE> for one rule or sprocket explain --tag <TAG> for every lint rule with a tag. Disable selected rules with configuration or lint directives; see Exceptions.

Rules from wdl-lint are listed as Lint rules. Rules from wdl-analysis are listed as Validation rules. Validation rules do not expose lint tags.

Summary ​

RuleKindTagsDescription
BashSetSyntaxLintCorrectnessEnsures that all command sections start with a valid set command.
CommandSectionIndentationValidation—Ensures consistent indentation (no mixed spaces/tabs) within command sections.
ConciseInputLintStyleEnsures concise input assignments are used (implicit binding when available).
ContainerUriLintClarity, PortabilityEnsures that values for the container key within runtime/requirements sections are well-formed.
DeclarationNameLintNaming, Style, ClarityEnsures declaration names do not redundantly include their type name.
DenyGlobStarLintClarity, CorrectnessEnsures glob("*") is not used in output declarations.
DeprecatedInputKeywordValidation—Ensures that the input: keyword is not used in call statements when WDL version is 1.2 or later.
DeprecatedObjectValidation—Ensures that the deprecated Object types are not used.
DeprecatedPlaceholderValidation—Ensures that deprecated expression placeholder options are not used.
DeprecatedRuntimeKeyLintCompleteness, DeprecatedDetects WDL 1.1 runtime keys that have preferred replacements.
DeprecatedRuntimeSectionValidation—Detects deprecated runtime sections.
DocCommentTabsLintStyle, ClarityEnsures that doc comments do not contain tab characters.
EmptyDocCommentLintClarity, DocumentationEnsures that documentation comment blocks are not empty.
EmptyOutputsLintCompletenessEnsures tasks specify an output section.
ExceptDirectiveValidValidation—Ensures except directives are placed correctly to have the intended effect.
ExtraneousParameterMetaLintCompleteness, Sorting, Documentation, SprocketCompatibilityEnsures that parameter_meta sections do not contain extraneous keys.
FlaggedCommentLintStyleFlags keywords in comments (by default, TODO) to ensure they are not forgotten.
HereDocCommandsLintClarity, CorrectnessEnsures that tasks use heredoc syntax in command sections.
HostPathLiteralsLintPortabilityFlags File/Directory declaration defaults that use absolute host paths.
ImportPlacementLintClarityEnsures that imports are placed between the version statement and any document items.
InlineInstallLintPortability, Correctness, PerformanceEnsures inline installation of packages is not used in command sections.
InputNameLintNaming, StyleEnsures input names are meaningful (e.g. not generic like 'input', 'in', or too short).
KnownRulesValidation—Ensures only known rules are used in except directives.
MatchingOutputMetaLintCompleteness, Documentation, SprocketCompatibilityEnsures that each output field is documented either in meta.outputs or with a doc comment.
MeaninglessLintDirectiveValidation—Warns if an #@ except: comment doesn't actually suppress a lint.
MetaDescriptionLintCompleteness, Documentation, SprocketCompatibilityEnsures that items with a meta section either contain a description key or a doc comment.
MetaSectionsLintCompleteness, Clarity, DocumentationEnsures that tasks, workflows, and structs have the required meta and parameter_meta sections, or supplementary doc comments.
MisleadingDeclarationOrderValidation—Warns when a variable declaration is placed after a command block.
MissingParameterMetaLintCompleteness, Sorting, Documentation, SprocketCompatibilityEnsures that inputs and struct fields have parameter_meta entries or supplementary doc comments.
MutableContainerTagLintClarity, PortabilityEnsures that container URIs use immutable tags.
NamingConventionLintNaming, Style, ClarityEnsures that tasks, workflows, variables, and types follow the configured naming conventions.
OutputMetaOrderLintCompleteness, Documentation, SprocketCompatibilityEnsures that meta.outputs keys are in the same order as output declarations.
OutputNameLintNaming, StyleEnsures output names are meaningful (e.g. not generic like 'output', 'out', or too short).
ParameterDescriptionLintCompleteness, DocumentationEnsures that parameters and outputs have proper descriptions.
ParameterMetaOrderLintCompleteness, Sorting, Documentation, SprocketCompatibilityEnsures that parameter_meta keys follow input declaration order.
RecommendedRuntimeKeysLintCompleteness, DeprecatedEnsures that WDL 1.0 and 1.1 runtime sections include recommended keys.
RedundantContainerArrayLintClarity, PortabilityEnsures that single-item container arrays are written as string literals.
RedundantNoneLintStyleFlags redundant assignment of None to optional inputs.
RequirementsSectionLintCompleteness, PortabilityEnsures that tasks have a requirements section (for WDL v1.2 and beyond).
RuntimeSectionLintCompleteness, PortabilityEnsures that tasks have a runtime section (for WDL v1.1 and prior).
ShellCheckLintCorrectnessEnsures that command blocks are free of ShellCheck violations.
ShellSplittingLintCorrectnessEnsures that String, File, and Directory values in command sections are quoted.
UnknownRuntimeKeysLintCompleteness, DeprecatedEnsures that WDL 1.1 runtime sections use reserved keys.
UnnecessaryFunctionCallValidation—Ensures that function calls are necessary.
UnusedCallValidation—Ensures that outputs of a call statement are used in the declaring workflow.
UnusedDeclarationValidation—Ensures that private declarations in tasks or workspaces are used within the declaring task or workspace.
UnusedDocCommentsLintDocumentationReports doc comments that are either floating or attached to WDL items that don't support them.
UnusedImportValidation—Ensures that import namespaces are used in the importing document.
UnusedInputValidation—Ensures that task or workspace inputs are used within the declaring task or workspace.
UsingFallbackVersionValidation—Warns if interpretation of a document with an unsupported version falls back to a default.

Tags ​

Definitions ​

WDL Document Structure ​

Preamble ​

The document preamble is defined as anything before the version declaration statement and the version declaration statement itself. Only comments and whitespace are permitted before the version declaration.

Comment Types ​

Lint Directives ​

Lint directives are special comments that begin with #@ except: followed by a comma-delimited list of rule IDs. These comments are used to disable specific lint rules for a section of the document. When a lint directive is encountered in the preamble, it will disable the specified rules for the entire document.

For example:

wdl
#@ except: DoubleQuotes, ConciseInput

Preamble Comments ​

Preamble comments are special comments at the start of a WDL file that begin with double pound signs (##). These comments are used for documentation that doesn't fit within any of the WDL-defined documentation elements (i.e., meta and parameter_meta sections). They may provide context for a collection of tasks or structs, or they may provide a high-level overview of a workflow. Preamble comments can be formatted as Markdown text.

For example:

wdl
## # FlagFilter
##
## A struct to represent the filtering flags used in various `samtools` commands.

BashSetSyntax ​

  • Kind: Lint
  • Tags: Correctness

Ensures that all command sections start with a valid set command.

Bash has many silent failure cases, which can produce invalid results and be difficult to debug. The set command should be used in all command sections to enforce stricter behavior.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

bash_set_options ​

  • Default: ["errexit","nounset","pipefail"]

List of options to enforce in the bash set builtin for every command section.

Example ​
toml
 [check.rules.BashSetSyntax]
 bash_set_options = ["errexit", "nounset", "pipefail"]

Examples ​

Problem

wdl
version 1.3

task say_hello {
    command <<<
        echo "Hello, World!"
    >>>
}

Assuming the default configuration

wdl
version 1.2

task say_hello {
    command <<<
        set -euo pipefail
        echo "Hello, World!"
    >>>
}

CommandSectionIndentation ​

  • Kind: Validation
  • Tags: None

Ensures consistent indentation (no mixed spaces/tabs) within command sections.

Mixing indentation (tab and space) characters within the command line causes leading whitespace stripping to be skipped. Commands may be whitespace sensitive, and skipping the whitespace stripping step may cause unexpected behavior.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.3

task say_greetings {
    input {
        String name
    }

    command <<<
        # this line is prefixed with tabs
		echo "Hello, ~{name}!"
        # this line is prefixed with spaces
        echo "Goodbye, ~{name}!"
    >>>
}

Revision

wdl
version 1.3

task say_greetings {
    input {
        String name
    }

    command <<<
        # this line is prefixed with spaces
        echo "Hello, ~{name}!"
        # this line is prefixed with spaces
        echo "Goodbye, ~{name}!"
    >>>
}

ConciseInput ​

  • Kind: Lint
  • Tags: Style

Ensures concise input assignments are used (implicit binding when available).

Redundant input assignments can be shortened in WDL versions >=v1.1 with an implicit binding. For example, { input: a = a } can be shortened to { input: a }.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

workflow hello {
    input {
        String name
    }

    # Since WDL v1.1, these explicit bindings can be shortened.
    call say_hello {
        name = name,
    }
}

task say_hello {
    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>
}

Revision

wdl
version 1.2

workflow hello {
    input {
        String name
    }

    # `name` can be passed in directly
    call say_hello {
        name,
    }
}

task say_hello {
    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>
}

ContainerUri ​

Ensures that values for the container key within runtime/requirements sections are well-formed.

This rule checks the following:

  • Containers should have a tag, as container URIs with no tags have no expectation that the behavior of the containers won't change between runs.
  • Use of the 'any' container URI (*) within an array of container URIs is ambiguous and should be avoided.
  • Empty container URI arrays are not disallowed by the specification but are ambiguous and should be avoided.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

task say_hello {
    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>

    # No tag
    requirements {
        container: "ubuntu"
    }
}

Revision

wdl
version 1.2

task say_hello {
    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>

    requirements {
        container: "ubuntu@sha256:cc925e589b7543b910fea57a240468940003fbfc0515245a495dd0ad8fe7cef1"
    }
}

DeclarationName ​

Ensures declaration names do not redundantly include their type name.

Declaration names should not include their type. This makes the code more verbose and often redundant. For example, use 'counter' instead of 'counter_int' or 'is_active' instead of 'is_active_bool'. Exceptions are made for String, File, and user-defined struct types, which are not flagged by this rule.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

allowed_names ​

  • Default: []

List of declaration names to ignore.

Example ​
toml
 [check.rules.DeclarationName]
 allowed_names = ["counter_int"]

Examples ​

Problem

wdl
version 1.2

task example {
    input {
        Int total_count_int
    }
}

Revision

wdl
version 1.2

task example {
    input {
        Int total_count
    }
}

DenyGlobStar ​

  • Kind: Lint
  • Tags: Clarity, Correctness

Ensures glob("*") is not used in output declarations.

glob("*") captures all files; as a task grows, you may include unintended files and cause unnecessary aggregation. Prefer explicit patterns to opt in only to the files you need, keeping tasks easier to debug/reproduce.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

task generate_files {
    command <<<
        touch foo.txt
        touch bar.txt
    >>>

    output {
        Array[File] files = glob("*")
    }
}

Revision

wdl
version 1.2

task generate_files {
    command <<<
        touch foo.txt
        touch bar.txt
    >>>

    output {
        # Specifically collect the .txt files
        Array[File] files = glob("*.txt")
    }
}

DeprecatedInputKeyword ​

  • Kind: Validation
  • Tags: None

Ensures that the input: keyword is not used in call statements when WDL version is 1.2 or later.

Starting with WDL version 1.2, the input: keyword in call statements is optional. This specification change allows call inputs to be specified directly within the braces without the input: keyword, resulting in a cleaner and more concise syntax. This rule encourages adoption of the newer syntax when using WDL 1.2 or later.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

workflow example {
    # In versions prior to WDL v1.2, the `input:` keyword
    # was necessary in `call` statements.
    call say_hello { input:
        name = "world",
    }
}

Revision

wdl
version 1.2

workflow example {
    # This is correct for WDL v1.2 and later.
    call say_hello {
        name = "world",
    }
}

DeprecatedObject ​

  • Kind: Validation
  • Tags: None

Ensures that the deprecated Object types are not used.

WDL Object types are officially deprecated and will be removed in the next major WDL release.

Objects existed prior to better containers, such as Maps and Structs, being introduced into the language. Unfortunately, though these better alternatives did exist at the time of the v1.0 release, the type was not removed. It was later decided that Objects overlapped with Maps and Structs in functionality, and the type was marked for removal.

See this issue for more details: https://github.com/openwdl/wdl/pull/228.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

workflow example {
    Object person = object {
        name: "Jimmy",
        age: 55,
    }
}

Consider switching to a Struct or Map

wdl
version 1.2

struct Person {
    String name
    Int age
}

workflow example {
    Person person = Person {
        name: "Jimmy",
        age: 55,
    }
}

DeprecatedPlaceholder ​

  • Kind: Validation
  • Tags: None

Ensures that deprecated expression placeholder options are not used.

Expression placeholder options were deprecated in WDL v1.1 and will be removed in the next major WDL version.

  • sep placeholder options should be replaced by the sep() standard library function.
  • true/false placeholder options should be replaced with if/else statements.
  • default placeholder options should be replaced by the select_first() standard library function.
  • ${} interpolation placeholders should be replaced by ~{} interpolation placeholders.

This rule only evaluates for WDL V1 documents with a version of v1.1 or later, as this was the version where the deprecation was introduced.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

workflow example {
    Array[String] names = [
        "James",
        "Jimmy",
        "John",
    ]
    String names_separated = "~{sep="," names}"
    String names_interpolated = "${names_separated}"
}

Revision

wdl
version 1.2

workflow example {
    Array[String] names = [
        "James",
        "Jimmy",
        "John",
    ]
    String names_separated = "~{sep(",", names)}"
    String names_interpolated = "~{names_separated}"
}

DeprecatedRuntimeKey ​

Detects WDL 1.1 runtime keys that have preferred replacements.

Some WDL 1.1 runtime keys are deprecated in favor of renamed keys. Using the current key names makes runtime requirements clearer and easier for execution engines to interpret.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.1

task old_container_key {
    runtime {
        docker: "ubuntu:latest"
    }
}

Revision

wdl
version 1.1

task old_container_key {
    runtime {
        container: "ubuntu:latest"
    }
}

DeprecatedRuntimeSection ​

  • Kind: Validation
  • Tags: None

Detects deprecated runtime sections.

The runtime section is deprecated in WDL v1.2 and later. Replace it with a requirements section.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

task say_hello {
    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>

    runtime {
        container: "ubuntu:latest"
    }
}

Revision

wdl
version 1.2

task say_hello {
    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>

    requirements {
        container: "ubuntu:latest"
    }
}

DocCommentTabs ​

  • Kind: Lint
  • Tags: Style, Clarity

Ensures that doc comments do not contain tab characters.

Tabs render with different widths depending on the viewer. Doc comments should use spaces instead of tabs to ensure consistent rendering.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.3

# Using tabs for alignment

##  {
##		"foo": 123,
##		^^^^^
##	}
workflow example {
    meta {
        description: 123
    }
}

Revision

wdl
version 1.3

# Using spaces for alignment

## {
##     "foo": 123,
##     ^^^^^
## }
workflow example {
    meta {
        description: "123"
    }
}

EmptyDocComment ​

Ensures that documentation comment blocks are not empty.

Documentation comment blocks (consecutive lines starting with ##) where all lines are empty serve no purpose. Either add meaningful text to the documentation comment block or remove it entirely.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

# This will render nothing!

##
struct Person {
    String name
    Int age
}

EmptyOutputs ​

  • Kind: Lint
  • Tags: Completeness

Ensures tasks specify an output section.

A task without an output section may be a mistake. This lint may be overzealous, as there are some legitimate use cases for tasks without outputs (e.g. uploading to an external service). In that case, authors should suppress the diagnostic on that specific task, and document its behavior in the meta section.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

task generate_files {
    command <<<
        touch foo.txt
    >>>
}

If the results are intended to be received by the caller

wdl
version 1.2

task generate_files {
    command <<<
        touch foo.txt
    >>>

    output {
        File files = "foo.txt"
    }
}

ExceptDirectiveValid ​

  • Kind: Validation
  • Tags: None

Ensures except directives are placed correctly to have the intended effect.

When writing WDL, except directives are used to suppress certain rules. If an except directive is misplaced, it will have no effect. This rule flags misplaced except directives to ensure they are in the correct location.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.3

# UsingFallbackVersion exceptions aren't valid
# in this context
#@ except: UsingFallbackVersion
workflow example {
}

Revision

wdl
#@ except: UsingFallbackVersion
version 1.3

workflow example {
}

ExtraneousParameterMeta ​

Ensures that parameter_meta sections do not contain extraneous keys.

Every key in a parameter_meta section should document a matching task input, workflow input, or struct field. Keys without matching declarations are stale or misleading.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.3

task say_hello {
    parameter_meta {
        name: "The name of the person to greet"
        does_not_exist: "This is not a real parameter"
    }

    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>
}

Revision

wdl
version 1.3

task say_hello {
    parameter_meta {
        name: "The name of the person to greet"
    }

    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>
}

FlaggedComment ​

  • Kind: Lint
  • Tags: Style

Flags keywords in comments (by default, TODO) to ensure they are not forgotten.

When writing WDL, future tasks are often marked with a keyword like TODO. This indicates that the implementor intended to go back to the code and handle the item. Flagged items should not be long-term fixtures within code and, as such, comments containing them are flagged to ensure none are forgotten. The keywords to flag are configurable with the keywords option and default to TODO. Keywords are matched as case-sensitive substrings of the comment text. If keywords overlap (e.g., FIX and FIXME), only the longest is reported.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

keywords ​

  • Default: ["TODO"]

List of keywords to flag in comments.

Keywords are matched as case-sensitive substrings of the comment text, and cannot be empty. When keywords overlap (for example, FIX and FIXME), the longest keyword is reported.

Example ​
toml
 [check.rules.FlaggedComment]
 keywords = ["TODO", "FIXME", "XXX"]

Examples ​

The following comment will be flagged

wdl
version 1.2

# TODO: Implement this workflow
workflow example {
    meta {
    }

    output {
    }
}

HereDocCommands ​

  • Kind: Lint
  • Tags: Clarity, Correctness

Ensures that tasks use heredoc syntax in command sections.

Curly command blocks are no longer considered idiomatic WDL. Idiomatic WDL code uses heredoc command blocks instead. This is because curly command blocks create ambiguity with Bash syntax.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

task say_hello {
    command {
        echo "Hello, World!"
    }
}

Revision

wdl
version 1.2

task say_hello {
    command <<<
        echo "Hello, World!"
    >>>
}

HostPathLiterals ​

  • Kind: Lint
  • Tags: Portability

Flags File/Directory declaration defaults that use absolute host paths.

File and Directory declarations with absolute path defaults are not portable across environments. Use relative paths or supply values at runtime.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.3

task run_tool {
    input {
        File data = "/etc/host/input.txt"
    }

    command <<<
        echo "run"
    >>>
}

ImportPlacement ​

  • Kind: Lint
  • Tags: Clarity

Ensures that imports are placed between the version statement and any document items.

All import statements should follow the WDL version declaration with one empty line between the version and the first import statement.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

workflow example {
}

import "example2.wdl"

Revision

wdl
version 1.2

import "example2.wdl"

workflow example {
}

InlineInstall ​

  • Kind: Lint
  • Tags: Portability, Correctness, Performance

Ensures inline installation of packages is not used in command sections.

All required software should be installed in the execution environment before the workflow is run. Inline installations can lead to lack of reproducibility, portability, and incur a performance cost, as software must be downloaded and installed every invocation.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.3

task say_hello {
    command <<<
        sudo apt install python3

        python3 -c "print('Hello, world!')"
    >>>

    requirements {
        container: "debian:trixie"
    }
}

Consider using a dedicated container image

wdl
version 1.3

task say_hello {
    command <<<
        python3 -c "print('Hello, world!')"
    >>>

    requirements {
        container: "python:trixie"
    }
}

InputName ​

Ensures input names are meaningful (e.g. not generic like 'input', 'in', or too short).

By default, any input name matching these regular expressions will be flagged: /^[iI]n[A-Z_]/, /^input/i or /^..?$/.

It is redundant and needlessly verbose to use an input's name to specify that it is an input. Input names should be short yet descriptive. Prefixing a name with "in" or "input" adds length to the name without adding clarity or context. Additionally, short names can lead to confusion and obfuscate the content of an input. Input names should be at least min_length characters long.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

min_length ​

  • Default: 3

The minimum length of input names; shorter names are flagged.

Example ​
toml
 [check.rules.InputName]
 min_length = 5

check_prefixes ​

  • Default: true

Whether to flag input names that start with a disallowed prefix (in/In followed by an uppercase letter or underscore, or input).

Example ​
toml
 [check.rules.InputName]
 check_prefixes = false

Examples ​

Problem

wdl
version 1.2

task say_hello {
    input {
        String input_name
    }

    command <<<
        echo "Hello, ~{input_name}!"
    >>>
}

Revision

wdl
version 1.2

task say_hello {
    meta {
        description: "Says hello for the given name"
    }

    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>
}

KnownRules ​

  • Kind: Validation
  • Tags: None

Ensures only known rules are used in except directives.

When writing WDL, except directives are used to suppress certain rules. If a rule is unknown, nothing will be suppressed. This rule flags unknown rules as they are often mistakes.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
#@ except: LintThatDoesNotExist
version 1.2

workflow example {
}

Revision

wdl
version 1.2

workflow example {
}

MatchingOutputMeta ​

Ensures that each output field is documented either in meta.outputs or with a doc comment.

Each task or workflow output without a doc comment should have a corresponding entry in the meta.outputs object. Entries for undeclared outputs are not allowed.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

task generate_greeting {
    meta {
        outputs: {
        # Missing `greeting`
        }
    }

    input {
        String name
    }

    output {
        String greeting = "Hello, ~{name}!"
    }
}

Revision

wdl
version 1.2

task generate_greeting {
    meta {
        outputs: {
            greeting: "The generated greeting for the provided name",
        }
    }

    input {
        String name
    }

    output {
        String greeting = "Hello, ~{name}!"
    }
}

MeaninglessLintDirective ​

  • Kind: Validation
  • Tags: None

Warns if an #@ except: comment doesn't actually suppress a lint.

Unused #@ except: comments are likely leftovers of refactoring or debugging, and can reduce the clarity of the code. It is best to remove them.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.3

task do_work {
    command <<<
        echo "Lots of hard work!"
    >>>

    output {
        String result = read_string(stdout())
    }
}

# We except `UnusedCall` unnecessarily.
workflow calculate {
    #@ except: UnusedCall
    call do_work

    output {
        # We're using the result here!
        String result = do_work.result
    }
}

Consider removing the unused exception

wdl
version 1.3

task do_work {
    command <<<
        echo "Lots of hard work!"
    >>>

    output {
        String result = read_string(stdout())
    }
}

workflow calculate {
    call do_work

    output {
        String result = do_work.result
    }
}

MetaDescription ​

Ensures that items with a meta section either contain a description key or a doc comment.

Each task, workflow, and struct should have a short description available. It should be written in active voice, and be in complete sentences. More detailed information can either be included in the help key, or subsequent paragraphs of a doc comment.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

task say_hello {
    meta {
    }

    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>
}

Revision

wdl
version 1.2

task say_hello {
    meta {
        description: "Says hello for the given name"
    }

    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>
}

MetaSections ​

Ensures that tasks, workflows, and structs have the required meta and parameter_meta sections, or supplementary doc comments.

It is important that WDL code is well-documented. Every task, workflow and struct should be documented with both a meta and parameter_meta section, or doc comments. Tasks without an input section are permitted to skip the parameter_meta section. WDL 1.0/1.1 structs don't support the meta or parameter_meta sections but require doc comments instead.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

task say_hello {
    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>
}

Revision

wdl
version 1.2

task say_hello {
    meta {
        description: "Says hello for the given name"
    }

    parameter_meta {
        name: "The name of the person to greet"
    }

    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>
}

MisleadingDeclarationOrder ​

  • Kind: Validation
  • Tags: None

Warns when a variable declaration is placed after a command block.

WDL tasks are evaluated based on their dependency graph, not top-to-bottom. Variable declarations that appear after command sections are visually misleading, as they will still be evaluated before the command is executed.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

task greet {
    String greeting = "Hello"

    command <<<
        echo "~{greeting}, ~{name}!"
    >>>

    String name = "World"
}

Revision

wdl
version 1.2

task greet {
    String greeting = "Hello"
    String name = "World"

    command <<<
        echo "~{greeting}, ~{name}!"
    >>>
}

MissingParameterMeta ​

Ensures that inputs and struct fields have parameter_meta entries or supplementary doc comments.

Each input parameter within a task or workflow and each struct field should have an associated parameter_meta entry or doc comment with a detailed description.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

task say_hello {
    parameter_meta {
    }

    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>
}

Revision

wdl
version 1.2

task say_hello {
    parameter_meta {
        name: "The name of the person to greet"
    }

    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>
}

MutableContainerTag ​

  • Kind: Lint
  • Tags: Clarity, Portability
  • Related rules: ContainerUri

Ensures that container URIs use immutable tags.

Immutable containers tagged with SHA256 sums are preferred. This is due to the requirement from the WDL specification that tasks produce functionally equivalent output across runs. When a mutable tag is used, there is a risk that changes to the container will cause different behavior between runs.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.3

task say_hello {
    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>

    requirements {
        container: "ubuntu:latest"
    }
}

Revision

wdl
version 1.3

task say_hello {
    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>

    requirements {
        container: "ubuntu@sha256:cc925e589b7543b910fea57a240468940003fbfc0515245a495dd0ad8fe7cef1"
    }
}

NamingConvention ​

Ensures that tasks, workflows, variables, and types follow the configured naming conventions.

Names should follow a consistent case convention. By default, tasks, workflows, variables, and struct members use snake_case, and user-defined type names (structs, enums, and enum choices) use PascalCase. The case style for each category can be configured. Maintaining a consistent naming convention makes the code easier to read and understand.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

task ​

  • Default: "snake_case"

The case style for task names.

One of snake_case, screaming_snake_case, camel_case, or pascal_case. Defaults to snake_case.

Example ​
toml
 [check.rules.NamingConvention]
 task = "pascal_case"

workflow ​

  • Default: "snake_case"

The case style for workflow names.

One of snake_case, screaming_snake_case, camel_case, or pascal_case. Defaults to snake_case.

Example ​
toml
 [check.rules.NamingConvention]
 workflow = "pascal_case"

variable ​

  • Default: "snake_case"

The case style for input, output, and private declaration names.

One of snake_case, screaming_snake_case, camel_case, or pascal_case. Defaults to snake_case.

Example ​
toml
 [check.rules.NamingConvention]
 variable = "camel_case"

type ​

  • Default: "pascal_case"

The case style for the names of user-defined types: structs, enums, and enum choices.

One of snake_case, screaming_snake_case, camel_case, or pascal_case. Defaults to snake_case.

Example ​
toml
 [check.rules.NamingConvention]
 type = "camel_case"

struct_member ​

  • Default: "snake_case"

The case style for struct member names.

One of snake_case, screaming_snake_case, camel_case, or pascal_case. Defaults to snake_case.

Example ​
toml
 [check.rules.NamingConvention]
 struct_member = "camel_case"

allowed_names ​

  • Default: []

List of names to ignore.

Example ​
toml
 [check.rules.NamingConvention]
 allowed_names = ["Foo"]

Examples ​

Problem

wdl
version 1.3

task SayHello {
    command <<<
        echo "Hello, World!"
    >>>
}

Revision

wdl
version 1.3

task say_hello {
    command <<<
        echo "Hello, World!"
    >>>
}

OutputMetaOrder ​

  • Kind: Lint
  • Tags: Completeness, Documentation, SprocketCompatibility
  • Related rules: MatchingOutputMeta

Ensures that meta.outputs keys are in the same order as output declarations.

When outputs without doc comments are documented in meta.outputs, those metadata keys should appear in the same order as their corresponding declarations in the output section.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.3

task ordered_outputs {
    meta {
        outputs: {
            second: "The second output",
            first: "The first output",
        }
    }

    output {
        String first = "one"
        String second = "two"
    }
}

Revision

wdl
version 1.3

task ordered_outputs {
    meta {
        outputs: {
            first: "The first output",
            second: "The second output",
        }
    }

    output {
        String first = "one"
        String second = "two"
    }
}

OutputName ​

Ensures output names are meaningful (e.g. not generic like 'output', 'out', or too short).

By default, any output name matching these regular expressions will be flagged: /^[oO]ut[A-Z_]/, /^output/i or /^..?$/.

It is redundant and needlessly verbose to use an output's name to specify that it is an output. Output names should be short yet descriptive. Prefixing a name with "out" or "output" adds length to the name without adding clarity or context. Additionally, short names can lead to confusion and obfuscate the content of an output. Output names should be at least min_length characters long.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

min_length ​

  • Default: 3

The minimum length of output names; shorter names are flagged.

Example ​
toml
 [check.rules.OutputName]
 min_length = 5

check_prefixes ​

  • Default: true

Whether to flag output names that start with a disallowed prefix (out/Out followed by an uppercase letter or underscore, or output).

Example ​
toml
 [check.rules.OutputName]
 check_prefixes = false

Examples ​

Problem

wdl
version 1.2

task generate_greeting {
    input {
        String name
    }

    command <<<
    >>>

    output {
        String output_greeting = "Hello, ~{name}!"
    }
}

Revision

wdl
version 1.2

task generate_greeting {
    input {
        String name
    }

    command <<<
    >>>

    output {
        String greeting = "Hello, ~{name}!"
    }
}

ParameterDescription ​

Ensures that parameters and outputs have proper descriptions.

Documentation is expected for each parameter (in parameter_meta) and each output (in meta.outputs). A valid description is either a simple String value or an object containing a description key with a String value.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

task greet {
    meta {
        outputs: {
            greeting: {},
        }
    }

    parameter_meta {
        name: {}
    }

    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}"
    >>>

    output {
        String greeting = stdout()
    }
}

Revision

wdl
version 1.2

task greet {
    meta {
        outputs: {
            greeting: "The generated greeting message.",
        }
    }

    parameter_meta {
        name: "The name of the person to greet."
    }

    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}"
    >>>

    output {
        String greeting = stdout()
    }
}

ParameterMetaOrder ​

Ensures that parameter_meta keys follow input declaration order.

When inputs or struct fields are documented in parameter_meta, the metadata keys should appear in the same order as the declarations they document.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.3

task say_hello {
    parameter_meta {
        punctuation: "The punctuation to use"
        name: "The name of the person to greet"
    }

    input {
        String name
        String punctuation = "!"
    }

    command <<<
        echo "Hello, ~{name}~{punctuation}"
    >>>
}

Revision

wdl
version 1.3

task say_hello {
    parameter_meta {
        name: "The name of the person to greet"
        punctuation: "The punctuation to use"
    }

    input {
        String name
        String punctuation = "!"
    }

    command <<<
        echo "Hello, ~{name}~{punctuation}"
    >>>
}

RecommendedRuntimeKeys ​

Ensures that WDL 1.0 and 1.1 runtime sections include recommended keys.

WDL 1.0 and 1.1 recommend runtime keys that improve task portability. In WDL 1.0, docker and memory are recommended. In WDL 1.1, container is recommended.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.1

task missing_container_key {
    runtime {
    }
}

Revision

wdl
version 1.1

task missing_container_key {
    runtime {
        container: "ubuntu:latest"
    }
}

RedundantContainerArray ​

  • Kind: Lint
  • Tags: Clarity, Portability
  • Related rules: ContainerUri

Ensures that single-item container arrays are written as string literals.

An array of container URIs with a single element is redundant and should be changed to a single string value.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.3

task say_hello {
    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>

    requirements {
        container: [
            "ubuntu@sha256:cc925e589b7543b910fea57a240468940003fbfc0515245a495dd0ad8fe7cef1",
        ]
    }
}

Revision

wdl
version 1.3

task say_hello {
    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>

    requirements {
        container: "ubuntu@sha256:cc925e589b7543b910fea57a240468940003fbfc0515245a495dd0ad8fe7cef1"
    }
}

RedundantNone ​

  • Kind: Lint
  • Tags: Style

Flags redundant assignment of None to optional inputs.

The specification states that an optional input declaration (e.g., String? foo) is implicitly initialized to None if no default is provided. Therefore explicitly writing String? foo = None is equivalent to String? foo but adds unnecessary verbosity.

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

workflow example {
    input {
        String? name = None
    }
}

Revision

wdl
version 1.2

workflow example {
    input {
        String? name
    }
}

RequirementsSection ​

Ensures that tasks have a requirements section (for WDL v1.2 and beyond).

Tasks that don't declare requirements sections are unlikely to be portable.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

task say_hello {
    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>
}

Revision

wdl
version 1.2

task say_hello {
    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>

    requirements {
        container: "ubuntu:latest"
    }
}

RuntimeSection ​

Ensures that tasks have a runtime section (for WDL v1.1 and prior).

Tasks that don't declare runtime sections are unlikely to be portable.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.1

task say_hello {
    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>
}

Revision

wdl
version 1.1

task say_hello {
    input {
        String name
    }

    command <<<
        echo "Hello, ~{name}!"
    >>>

    runtime {
        container: "ubuntu:latest"
    }
}

ShellCheck ​

Ensures that command blocks are free of ShellCheck violations.

ShellCheck is a static analysis tool and linter for sh / bash. The lints provided by ShellCheck help prevent common errors and pitfalls in your scripts. Following its recommendations will increase the robustness of your command sections. Placeholders are replaced with shell variables or literals before ShellCheck runs. ShellCheck's word splitting diagnostics (SC2086, SC2206, and SC2231) are not reported for placeholders, because the ShellSplitting rule reports those using the types of the placeholder expressions.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

task say_hello {
    # Triggers SC2154
    command <<<
        echo "Hello $name"
    >>>
}

Revision

wdl
version 1.2

task say_hello {
    command <<<
        name=World
        echo "Hello $name"
    >>>
}

ShellSplitting ​

  • Kind: Lint
  • Tags: Correctness
  • Related rules: ShellCheck

Ensures that String, File, and Directory values in command sections are quoted.

When a placeholder in a command section is not quoted, the shell splits its value into separate words at whitespace and expands any glob characters. A file path or string that contains a space or a * then becomes several arguments or matches unintended files. This rule reports each String, File, or Directory value that is inserted into an unquoted part of the script, including values in individual branches of if expressions and elements of arrays joined with sep. Values inside shell quotes, assignments, [[ ]] tests, case words, arithmetic, heredoc bodies, and comments are not split and are not reported. Numbers and booleans are never reported. ShellCheck's SC2086, SC2206, and SC2231 diagnostics are not reported for placeholders, because this rule covers them.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Example 1 ​

Problem

wdl
version 1.2

task count_lines {
    input {
        File reads
    }

    command <<<
        wc -l ~{reads}
    >>>
}

Surround the placeholder with double quotes

wdl
version 1.2

task count_lines {
    input {
        File reads
    }

    command <<<
        wc -l "~{reads}"
    >>>
}

Example 2 ​

Problem

wdl
version 1.2

task view {
    input {
        File bam
        String? region
    }

    command <<<
        samtools view "~{bam}" ~{if defined(region) then "--region ~{region}" else ""}
    >>>
}

Quote the value inside the placeholder expression

wdl
version 1.2

task view {
    input {
        File bam
        String? region
    }

    command <<<
        samtools view "~{bam}" ~{if defined(region) then "--region '~{region}'" else ""}
    >>>
}

UnknownRuntimeKeys ​

Ensures that WDL 1.1 runtime sections use reserved keys.

The behavior of this rule is different depending on the WDL version:

For WDL v1.0 documents, this rule does not emit diagnostics.

For WDL v1.1 documents, the specification deprecates the inclusion of non-reserved keys in a runtime section. As such, any non-reserved keys will be flagged for removal.

For WDL v1.2 documents and later, this rule does not evaluate because runtime sections were deprecated in this version.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

allowed_runtime_keys ​

  • Default: []

List of runtime keys to ignore.

Example ​
toml
 [check.rules.UnknownRuntimeKeys]
 allowed_runtime_keys = ["foo"]

Examples ​

The following has an unexpected key

wdl
version 1.1

task unexpected_runtime_key {
    runtime {
        container: "ubuntu"
        foo: "bar"
    }
}

UnnecessaryFunctionCall ​

  • Kind: Validation
  • Tags: None

Ensures that function calls are necessary.

Unnecessary function calls may impact evaluation performance.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

workflow example {
    # Calls to `defined` on values that are statically
    # known to be non-None are unnecessary.
    Boolean exists = defined("hello")
}

UnusedCall ​

  • Kind: Validation
  • Tags: None

Ensures that outputs of a call statement are used in the declaring workflow.

Unused calls may cause unnecessary consumption of compute resources.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

workflow example {
    # The output of `do_work` is never used
    call do_work
}

task do_work {
    command <<<
    >>>

    output {
        Int x = 0
    }
}

Consider removing the call entirely

wdl
version 1.2

workflow example {
}

task do_work {
    command <<<
    >>>

    output {
        Int x = 0
    }
}

UnusedDeclaration ​

  • Kind: Validation
  • Tags: None

Ensures that private declarations in tasks or workspaces are used within the declaring task or workspace.

Unused private declarations degrade evaluation performance and reduce the clarity of the code.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

workflow example {
    String unused = "this will produce a warning"
}

Consider removing the declaration entirely

wdl
version 1.2

workflow example {
}

UnusedDocComments ​

  • Kind: Lint
  • Tags: Documentation

Reports doc comments that are either floating or attached to WDL items that don't support them.

Some Workflow Definition Language items do not support doc comments (##). This lint reports if a doc comment is attached to an item that isn't supported.

Doc comments are supported on:

  • Workflow Definitions
  • Task Definitions
  • Struct Definitions
  • Fields in Struct Definitions
  • Fields in Input Sections
  • Fields in Output Sections
  • Enum Definitions
  • Enum Choices

Additionally, outside the preamble, doc comments must immediately precede the item they intend to document with no blank lines between, otherwise they are considered "floating".

Configuration ​

severity ​

  • Default: "note"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

workflow example {
    # This isn't documenting anything!
    ## The inputs for the workflow
    input {
        String name
    }

    # Neither is this!
    ## The outputs for the workflow
    output {
        String greeting = "Hello, ~{name}!"
    }
}

Consider removing the comments or moving them to applicable items

wdl
version 1.2

workflow example {
    input {
        ## The name to greet
        String name
    }

    output {
        ## The generated greeting
        String greeting = "Hello, ~{name}!"
    }
}

UnusedImport ​

  • Kind: Validation
  • Tags: None

Ensures that import namespaces are used in the importing document.

Imported WDL documents should be used in the document that imports them. Unused imports impact parsing and evaluation performance.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.3

import "bar.wdl"
import "foo.wdl" as used

workflow example {
    call used.test
}

Consider removing the import entirely

wdl
version 1.3

import "foo.wdl" as used

workflow example {
    call used.test
}

UnusedInput ​

  • Kind: Validation
  • Tags: None

Ensures that task or workspace inputs are used within the declaring task or workspace.

Unused inputs degrade evaluation performance and reduce the clarity of the code. Unused file inputs in tasks can also cause unnecessary file localizations.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
version 1.2

workflow example {
    input {
        String unused
    }
}

Consider removing the input entirely

wdl
version 1.2

workflow example {
    input {
    }
}

UsingFallbackVersion ​

  • Kind: Validation
  • Tags: None

Warns if interpretation of a document with an unsupported version falls back to a default.

A document with an unsupported version may have unpredictable behavior if interpreted as a different version.

Configuration ​

severity ​

  • Default: "warning"

The severity of the rule's diagnostics: off, note or warning.

Examples ​

Problem

wdl
# Not a valid version. If a fallback version is configured,
# the document will be interpreted as that version.
version development

workflow example {
}

Search commands, configuration, and guides.