Skip to content

{{ env "NAME" }} template function returns empty for dotenv-injected variables, but works for shell-provided ones #3048

Closed

Description

@Diover

Description

First of all, I'd like to say thank you for creating such a neat task runner! It really is a pleasure to use.

I recently discovered a small inconsistency that I can't make a sense of. I've searched through the open issues (e.g. #2807), but couldn't find anything related. My apologies if this was already brought up somewhere else.

Description

When an environment variable is provided to the tasks from the shell, the {{ env "NAME" }} template function resolves it correctly in the task-level vars. However, when the same variable is loaded from a dotenv file, the injected variable resolves in cmds and in dynamic sh: vars, but {{ env "NAME" }} evaluates to an empty string.

Steps to reproduce

Given a Taskfile.yml:

version: "3"

dotenv:
  - .env

tasks:
  try-vars:
    silent: true
    vars:
      TOKEN_VAR:
        sh: echo ${TOKEN}
      TOKEN_VAR_TEMPLATE: '{{ env "TOKEN" }}'
    cmds:
      - echo "Token from env vars '${TOKEN}'"
      - echo "Token from task vars '{{ .TOKEN_VAR }}'"
      - echo "Token from env template '{{ .TOKEN_VAR_TEMPLATE }}'"
  1. The {{ env ... }} template resolves correctly for a variable from the shell environment:
$ TOKEN=super-secure-stuff task try-vars
Token from env vars 'super-secure-stuff'
Token from task vars 'super-secure-stuff'
Token from env template 'super-secure-stuff'
  1. The {{ env ... }} template does not resolve for a variable added via a dotenv file:
$ echo "TOKEN=super-secure-stuff" > .env && task try-vars
Token from env vars 'super-secure-stuff'
Token from task vars 'super-secure-stuff'
Token from env template ''

Expected behavior

I'd expect both cases to behave identically: {{ env "TOKEN" }} should return the value loaded from the dotenv file.

Actual behavior

{{ env "TOKEN" }} returns an empty string when TOKEN comes from a dotenv file, even though the same value is visible to command subprocesses (${TOKEN}) and to dynamic sh: vars.

This behavior feels inconsistent. The dotenv variables reach the environment in which sh: echo ${TOKEN} runs, but the template {{ env ... }} function does not see them.

System specs

  • Task version: v3.53.1
  • Operating system: macOS 15.7.3
  • Experiments enabled: No

Activity

  1. vmaerten commented on Sep 26, 2026

    @vmaerten
    Member

    Hello !
    You can use {{.TOKEN}} here:
    TOKEN_VAR_TEMPLATE: '{{.TOKEN}}'

    This works with both shell environment variables and your top-level dotenv file. The env function only reads Task’s process environment, which loading a dotenv file does not modify.

  2. added theissue type on Sep 26, 2026
  3. Diover commented on Sep 28, 2026

    @Diover
    Author

    @vmaerten Thanks for the pointer! Regular variables should work for my use case. I was just caught by surprise by the env function behavior, but it makes sense now knowing the loading priority.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Fields

    No fields configured for support.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions