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 *boolView on GitHub (pinned to 385e5ad92a)
Solutions
- Move the `dotenv:` declaration from the included Taskfile into the main (root) Taskfile
- Replace dotenv in the included file with explicit `vars:` that the includer can override, or pass env vars in the shell environment
- 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
- Keep `dotenv:` only in the root/main Taskfile by convention
- When splitting a Taskfile into includes, audit each moved section for dotenv/env declarations
- Prefer explicit `vars:` over dotenv in shared/included Taskfiles
- Add a CI lint step grepping included Taskfiles for a top-level dotenv key
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
- loop var must be a delimiter-separated string, list or a map
- task: precondition not met
- task: invalid run "%s"
- task: %w "%s"
- task: output style %q not recognized
AI-assisted analysis of go-task/task@385e5ad92a (2026-09-05).
Data as JSON: /api/errors/8cb3cb6eec30fb60.
Report an issue: GitHub.