JuliusBrussee/caveman · error

%s is required

Error message

%s is required

What it means

The only error in shared/platform/env/env.go Required(): the named environment variable is unset, empty, or whitespace-only after strings.TrimSpace. It is the library's generic 'mandatory configuration missing' signal and carries the variable name in the message.

Source

Thrown at shared/platform/env/env.go:48

	return parsed
}

func Int(name string, fallback int) int {
	v, ok := os.LookupEnv(name)
	if !ok || strings.TrimSpace(v) == "" {
		return fallback
	}
	parsed, err := strconv.Atoi(strings.TrimSpace(v))
	if err != nil {
		return fallback
	}
	return parsed
}

func Required(name string) (string, error) {
	v := strings.TrimSpace(os.Getenv(name))
	if v == "" {
		return "", fmt.Errorf("%s is required", name)
	}
	return v, nil
}

// IsProduction is the single definition of "this process runs in production".
// Every refusal gate must agree on it: a CAVE_ENV of " prod" or "PROD" that one
// check treated as production and another as local would arm half the production
// refusals and silently skip the rest. Whitespace and case are therefore folded
// in — the direction that turns MORE deployments on, never fewer.
func IsProduction() bool {
	return runtimeenv.IsProduction()
}

func RefuseProductionDefaults() error {
	if !IsProduction() {
		return nil
	}
	if err := validateProductionTextSecrets([]string{

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Export the variable with a non-empty value in the environment that runs the process.
  2. Check for name mismatches: compare the exact name in the error message against what your deployment injects.
  3. If using dotenv files, confirm they are loaded before the call and the line has no stray whitespace around the key.
  4. For optional variables, use env.String(name, fallback) instead of Required.

Example fix

# before
# CAVE_BOOTSTRAP_TOKEN=  (empty)

# after
CAVE_BOOTSTRAP_TOKEN=<32+ char token>
Defensive patterns

Strategy: try-catch

Validate before calling

for _, name := range []string{"CAVE_KEY_HASH_PEPPER", "CAVE_JWT_SIGNING_KEY"} {
    if strings.TrimSpace(os.Getenv(name)) == "" {
        return fmt.Errorf("missing required env %s", name)
    }
}

Try / catch

v, err := env.Required("CAVE_BOOTSTRAP_TOKEN")
if err != nil {
    return fmt.Errorf("configuration incomplete: %w", err) // name is already in the message
}

Prevention

When it happens

Trigger: Calling env.Required("SOME_VAR") in a process where SOME_VAR is not exported, is set to an empty string, or holds only spaces/tabs. The trimmed value is what is tested, so ' ' fails exactly like ''.

Common situations: A .env file not loaded in the deployed environment; secret injected under a slightly different name (CAVE_JWT_SIGNING_KEY vs JWT_KEY); variable commented out in the compose file; CI job missing an env block; trailing spaces around '=' in an env file creating a name with a space.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/bc472a0a8e25c389. Report an issue: GitHub.