direnv/direnv · critical
couldn't find a configuration directory for direnv
Error message
couldn't find a configuration directory for direnv
What it means
LoadConfig determines direnv's configuration directory: DIRENV_CONFIG first, then xdg.ConfigDir(env, "direnv"). If both are empty it cannot locate a config directory and returns this error, aborting configuration load.
Source
Thrown at internal/cmd/config.go:99
if homedir, homedirErr := os.UserHomeDir(); homedirErr == nil {
pathExpanded = filepath.Join(homedir, path[2:])
}
}
return pathExpanded
}
// LoadConfig opens up the direnv configuration from the Env.
func LoadConfig(env Env) (config *Config, err error) {
config = &Config{
Env: env,
}
config.ConfDir = env[DIRENV_CONFIG]
if config.ConfDir == "" {
config.ConfDir = xdg.ConfigDir(env, "direnv")
}
if config.ConfDir == "" {
err = fmt.Errorf("couldn't find a configuration directory for direnv")
return
}
var exePath string
if exePath, err = os.Executable(); err != nil {
err = fmt.Errorf("LoadConfig() os.Executable() failed: %w", err)
return
}
// Fix for mingsys
exePath = strings.ReplaceAll(exePath, "\\", "/")
config.SelfPath = exePath
var wdErr error
if config.WorkDir, wdErr = os.Getwd(); wdErr != nil {
// handled by `findEnvUp`
return //nolint:nilnesserr
}
View on GitHub (pinned to b00e451f54)
Solutions
- Set DIRENV_CONFIG to an explicit config directory: export DIRENV_CONFIG=~/.config/direnv.
- Ensure HOME is set in the execution environment (export HOME=/home/user).
- Set XDG_CONFIG_HOME (e.g. export XDG_CONFIG_HOME=$HOME/.config) so the XDG fallback resolves.
- Fix the service/container definition so the process runs as a user with a home directory.
Example fix
// before (systemd unit) ExecStart=/usr/bin/direnv export bash // after [Service] Environment=HOME=%h Environment=DIRENV_CONFIG=%h/.config/direnv ExecStart=/usr/bin/direnv export bash
Defensive patterns
Strategy: validation
Validate before calling
func hasConfigDir() bool {
if os.Getenv("DIRENV_CONFIG") != "" { return true }
if os.Getenv("XDG_CONFIG_HOME") != "" { return true }
home, err := os.UserHomeDir()
return err == nil && home != ""
}
if !hasConfigDir() { os.Setenv("DIRENV_CONFIG", filepath.Join(homeOrDefault(), ".config", "direnv")) } Try / catch
err := cmd.Run() // direnv invocation
if err != nil && strings.Contains(err.Error(), "couldn't find a configuration directory") {
// fix environment then retry
os.Setenv("DIRENV_CONFIG", filepath.Join(home, ".config", "direnv"))
err = cmd.Run()
} Prevention
- Always set HOME (or DIRENV_CONFIG) for services, cron jobs, and containers that run direnv.
- Never export DIRENV_CONFIG as an empty string.
- Smoke-test direnv in a stripped env (`env -i PATH=... direnv version`) before deploying.
- Run as a user with a home directory.
When it happens
Trigger: Calling LoadConfig (directly or via command Call) with DIRENV_CONFIG unset and an environment where XDG_CONFIG_HOME is unset/empty AND $HOME is unset/empty, so xdg.ConfigDir returns "".
Common situations: Running direnv from cron/systemd/init with a stripped environment lacking HOME; containers running as a user with no home directory; tests that clear the environment; setting DIRENV_CONFIG to an empty string.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- could not find a default editor in the PATH
- LoadConfig() failed to parse %s: %w
- missing PATH argument
- invalid arguments
- executable file not found in $PATH
AI-assisted analysis of direnv/direnv@b00e451f54 (2026-09-05).
Data as JSON: /api/errors/6614419395e36634.
Report an issue: GitHub.