go-task/task · error
error reading env file %s: %w
Error message
error reading env file %s: %w
What it means
Task reads .env files listed under `dotenv:` with godotenv.Read. If the file exists but cannot be read or parsed (bad permissions, malformed KEY=VALUE lines), the OS/parser error is wrapped in this message and returned.
Source
Thrown at taskfile/dotenv.go:31
func Dotenv(vars *ast.Vars, tf *ast.Taskfile, dir string) (*ast.Vars, error) {
env := ast.NewVars()
cache := &templater.Cache{Vars: vars}
for _, dotEnvPath := range tf.Dotenv {
dotEnvPath = templater.Replace(dotEnvPath, cache)
if dotEnvPath == "" {
continue
}
dotEnvPath = filepathext.SmartJoin(dir, dotEnvPath)
if _, err := os.Stat(dotEnvPath); os.IsNotExist(err) {
continue
}
envs, err := godotenv.Read(dotEnvPath)
if err != nil {
return nil, fmt.Errorf("error reading env file %s: %w", dotEnvPath, err)
}
for key, value := range envs {
if _, ok := env.Get(key); !ok {
env.Set(key, ast.Var{Value: value})
}
}
}
return env, nil
}
View on GitHub (pinned to 385e5ad92a)
Solutions
- Check file permissions so the Task process user can read the file (`chmod 644 .env`)
- Fix dotenv syntax: each line must be KEY=VALUE (quote values containing spaces/special chars)
- Ensure the dotenv path points to a regular file, not a directory
- Look at the wrapped `%w` cause in the message for the exact OS/parser error
Example fix
# before (.env) MY VAR = hello # after MY_VAR="hello"
Defensive patterns
Strategy: try-catch
Validate before calling
for _, f := range dotenvPaths {
if fi, err := os.Stat(f); err == nil && fi.IsDir() {
return fmt.Errorf("dotenv path %s is a directory", f)
}
if err := checkDotenvSyntax(f); err != nil {
return err
}
} Type guard
func isReadableFile(path string) bool {
fi, err := os.Stat(path)
return err == nil && fi.Mode().IsRegular() && fi.Mode().Perm()&0o400 != 0
} Try / catch
env, err := dotenv.Dotenv(vars, node, workingDir)
if err != nil {
var osErr *fs.PathError
if errors.As(err, &osErr) {
// handle unreadable/missing dotenv file
}
return fmt.Errorf("loading dotenv: %w", err)
} Prevention
- Validate .env syntax with dotenv linters in CI
- Keep dotenv entries pointing at regular files, not directories
- Check file permissions when running in containers/CI
- Quote values containing spaces or special characters
When it happens
Trigger: readDotEnvFiles -> Dotenv: a dotenv path passes the os.Stat existence check but godotenv.Read fails — e.g. permission denied, path is a directory, or the file has invalid dotenv syntax.
Common situations: A .env file with unparseable lines (spaces around =, missing values on quoted lines, junk characters); read-only or root-owned .env in CI; a `dotenv:` entry pointing at a directory instead of a file.
Related errors
- task: Included Taskfiles can't have dotenv declarations. Ple
- task: Blank Arch value provided
- task: Multiple Arch values provided
- task: Taskfiles versions should match. First is "%s" but sec
- failed to read CA certificate: %w
AI-assisted analysis of go-task/task@385e5ad92a (2026-09-05).
Data as JSON: /api/errors/f8bff22b3a9ac061.
Report an issue: GitHub.