charmbracelet/crush · error

env %q: %w

Error message

env %q: %w

What it means

This error is returned by resolveEnvs in internal/config/config.go when resolving the `env` map of a provider/LSP/MCP config entry fails. Each value is run through the resolver (which expands shell-style env references like {{ env:VAR }}); if any single entry fails to resolve, the whole resolution aborts and the key name is wrapped into the message. It indicates a bad or unresolvable environment-variable reference in the config, not a bug in Crush.

Source

Thrown at internal/config/config.go:613

// round-trip back to a map at the call site.
//
// See ResolvedArgs for guidance on picking a resolver.
func (l LSPConfig) ResolvedEnv(r VariableResolver) (map[string]string, error) {
	if len(l.Env) == 0 {
		return map[string]string{}, nil
	}
	out := make(map[string]string, len(l.Env))
	// Sort keys so failures are reported deterministically when more
	// than one value would fail.
	keys := make([]string, 0, len(l.Env))
	for k := range l.Env {
		keys = append(keys, k)
	}
	slices.Sort(keys)
	for _, k := range keys {
		v, err := r.ResolveValue(l.Env[k])
		if err != nil {
			return nil, fmt.Errorf("env %q: %w", k, err)
		}
		out[k] = v
	}
	return out, nil
}

type Agent struct {
	ID          string `json:"id,omitempty"`
	Name        string `json:"name,omitempty"`
	Description string `json:"description,omitempty"`
	// This is the id of the system prompt used by the agent
	Disabled bool `json:"disabled,omitempty"`

	Model SelectedModelType `json:"model" jsonschema:"required,description=The model type to use for this agent,enum=large,enum=small,default=large"`

	// The available tools for the agent
	//  if this is nil, all tools are available
	AllowedTools []string `json:"allowed_tools,omitempty"`

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Export the missing environment variable in the shell profile or environment where Crush runs.
  2. Fix the env reference syntax for that key in crushrc/crush.json (check the key name reported in the message).
  3. Replace the env reference with a literal value if dynamic resolution is not needed.
  4. If running under systemd/CI, ensure the variable is passed through to the process environment.

Example fix

// before (crushrc)
provider anthropic
  env ANTHROPIC_API_KEY "{{ env:ANTHROPOIC_API_KEY }}"  # typo: variable unset
end
// after
export ANTHROPIC_API_KEY=sk-...
provider anthropic
  env ANTHROPIC_API_KEY "{{ env:ANTHROPIC_API_KEY }}"
end
Defensive patterns

Strategy: validation

Validate before calling

for k, ref := range providerCfg.Env {
    if err := resolver.ResolveValue(ref); err != nil {
        return fmt.Errorf("env %q is not resolvable: %w", k, err)
    }
}

Type guard

func isResolvableEnvRef(ref string, lookup func(string) (string, bool)) bool {
    for _, name := range extractEnvNames(ref) {
        if _, ok := lookup(name); !ok {
            return false
        }
    }
    return true
}

Try / catch

var out map[string]string
if err := cfg.ResolveEnvs(); err != nil {
    var envErr *EnvResolveError
    if errors.As(err, &envErr) {
        log.Fatalf("set env var %s before starting: %v", envErr.Key, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling config loading/resolution for a provider, LSP, or MCP entry whose Env map contains a value that r.ResolveValue cannot resolve — typically a reference to an environment variable that is unset, or a malformed reference syntax.

Common situations: A crushrc/crush.json entry references an API key env var (e.g. {{ env:ANTHROPIC_API_KEY }}) that is not exported in the shell or .env file; a typo in the variable name; running Crush from a service/CI environment that lacks the interactive shell's exports.

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 charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/c689b9913051dd3a. Report an issue: GitHub.