go-task/task · error

task: Included Taskfiles can't have dotenv declarations. Ple

Error message

task: Included Taskfiles can't have dotenv declarations. Please, move the dotenv declaration to the main Taskfile

What it means

ErrIncludedTaskfilesCantHaveDotenvs is returned by Taskfile.Merge when an included Taskfile declares a top-level `dotenv:` section. Since dotenv files must be loaded before the main Taskfile is processed, and included Taskfiles are merged after that, dotenv declarations in included files cannot be honored — so Merge rejects them with this error. The dotenv declaration must live in the main (root) Taskfile instead.

Source

Thrown at taskfile/ast/taskfile.go:19

package ast

import (
	"fmt"
	"time"

	"github.com/Masterminds/semver/v3"
	"go.yaml.in/yaml/v3"

	"github.com/go-task/task/v3/errors"
)

// NamespaceSeparator contains the character that separates namespaces
const NamespaceSeparator = ":"

var V3 = semver.MustParse("3")

// ErrIncludedTaskfilesCantHaveDotenvs is returned when a included Taskfile contains dotenvs
var ErrIncludedTaskfilesCantHaveDotenvs = errors.New("task: Included Taskfiles can't have dotenv declarations. Please, move the dotenv declaration to the main Taskfile")

// Taskfile is the abstract syntax tree for a Taskfile
type Taskfile struct {
	Location     string
	Version      *semver.Version
	Output       Output
	Method       string
	Includes     *Includes
	Set          []string
	Shopt        []string
	Vars         *Vars
	Env          *Vars
	Tasks        *Tasks
	Silent       bool
	Dotenv       []string
	Run          string
	Interval     time.Duration
	UseGitignore *bool

View on GitHub (pinned to 385e5ad92a)

Solutions

  1. Move the `dotenv:` declaration from the included Taskfile into the main (root) Taskfile
  2. Replace dotenv in the included file with explicit `vars:` that the includer can override, or pass env vars in the shell environment
  3. Restructure includes so the file that needs the dotenv values is the main Taskfile, including others only for tasks

Example fix

# before — included Taskfile
# common/Taskfile.yml
dotenv: ['.env']
tasks:
  build: ...
# after — main Taskfile.yml
dotenv: ['.env']
includes:
  common: ./common
tasks:
  build: ...
Defensive patterns

Strategy: validation

Validate before calling

# Lint included Taskfiles for dotenv before running task:
grep -n '^dotenv:' $(find . -name 'Taskfile*.yml' -not -path './Taskfile.yml') && \
  echo 'ERROR: dotenv not allowed in included Taskfiles' && exit 1

Try / catch

if _, err := tf.Merge(); err != nil {
    if errors.Is(err, taskfile.ErrIncludedTaskfilesCantHaveDotenvs) {
        return fmt.Errorf("move dotenv to the main Taskfile: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: A Taskfile referenced via `includes:` contains `dotenv: ['...', ...]` at its top level. The error surfaces during Taskfile parsing/merging, before any task runs, whenever the included file is read.

Common situations: Refactoring a monolithic Taskfile into several included files and moving sections (including dotenv) wholesale; sharing a common Taskfile between projects where dotenv was included; copying examples written for older single-file setups. This is a Task v3 layout constraint.

Related errors


AI-assisted analysis of go-task/task@385e5ad92a (2026-09-05). Data as JSON: /api/errors/8cb3cb6eec30fb60. Report an issue: GitHub.