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

  1. Set DIRENV_CONFIG to an explicit config directory: export DIRENV_CONFIG=~/.config/direnv.
  2. Ensure HOME is set in the execution environment (export HOME=/home/user).
  3. Set XDG_CONFIG_HOME (e.g. export XDG_CONFIG_HOME=$HOME/.config) so the XDG fallback resolves.
  4. 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

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


AI-assisted analysis of direnv/direnv@b00e451f54 (2026-09-05). Data as JSON: /api/errors/6614419395e36634. Report an issue: GitHub.