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
- Export the missing environment variable in the shell profile or environment where Crush runs.
- Fix the env reference syntax for that key in crushrc/crush.json (check the key name reported in the message).
- Replace the env reference with a literal value if dynamic resolution is not needed.
- 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
- Document required env vars in the repo and assert them at startup.
- Use direnv or a checked-in .env.example to keep variable names consistent.
- Prefer literal config values over env references for non-secret settings.
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
- env %s: %w
- task agent not configured
- small model provider not configured
- coder agent not configured
- model provider not configured
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/c689b9913051dd3a.
Report an issue: GitHub.