googleapis/mcp-toolbox · error
environment variables not found: - %s
Error message
environment variables not found: - %s
What it means
Raised by ConfigParser.parseEnv when two or more required environment variables referenced in the config are missing. It is the plural variant of the 'environment variable not found' error and lists every missing name, one per ' - ' bullet, so all can be fixed in one pass instead of iterating one failure at a time.
Source
Thrown at cmd/internal/config.go:146
lastIndex = end
}
output.WriteString(input[lastIndex:])
// Filter out OptionalEnvVars that were also found as required
var finalOptional []string
for _, v := range p.OptionalEnvVars {
if !slices.Contains(p.requiredEnvVars, v) && !slices.Contains(finalOptional, v) {
finalOptional = append(finalOptional, v)
}
}
p.OptionalEnvVars = finalOptional
var err error
if len(missing) > 0 {
if len(missing) == 1 {
err = fmt.Errorf("environment variable not found: %s", missing[0])
} else {
err = fmt.Errorf("environment variables not found:\n - %s", strings.Join(missing, "\n - "))
}
}
return output.String(), err
}
// isInsideComment checks if the given 1-based rune offset in the YAML input is
// within a comment token. Token positions from the lexer are 1-based rune
// offsets, so callers must convert byte offsets before calling this.
func isInsideComment(tokens token.Tokens, runeOffset int) bool {
for _, t := range tokens {
if t.Type == token.CommentType && t.Position != nil {
// Position.Offset points at the "#", but Origin also carries any
// indentation that precedes it, so measure the length from the "#".
length := utf8.RuneCountInString(strings.TrimLeft(t.Origin, " \t"))
if runeOffset >= t.Position.Offset && runeOffset < t.Position.Offset+length {
return true
}View on GitHub (pinned to 8cc6e09de2)
Solutions
- Export every variable listed in the error message (each ' - ' bullet) before starting.
- Provide all variables via --env-file or your platform's secret/environment injection.
- Fix variable-name mismatches between the config placeholders and the actual environment.
- Mark genuinely optional variables as optional (OptionalEnvVars) so they are not required.
Example fix
# before: "environment variables not found:\n - DB_USER\n - DB_PASSWORD" ./toolbox --config tools.yaml # after export DB_USER="app" DB_PASSWORD="secret" ./toolbox --config tools.yaml
Defensive patterns
Strategy: validation
Validate before calling
for _, v := range []string{"DB_USER", "DB_PASSWORD", "DB_HOST"} {
if os.Getenv(v) == "" { log.Fatalf("missing env var: %s", v) }
} Try / catch
if strings.HasPrefix(err.Error(), "environment variables not found:") {
log.Fatalf("export each listed variable, or provide --env-file: %v", err)
} Prevention
- Maintain one .env file per environment and load it with --env-file.
- Add a preflight check in CI that asserts every ${VAR} in the config exists.
- When adding a new ${VAR} to a config, update .env.example and all deploy targets in the same PR.
When it happens
Trigger: Running `toolbox` with a config referencing multiple unset ${VAR} placeholders, e.g. both ${DB_USER} and ${DB_PASSWORD} not exported; commonly seen on fresh environments or CI runners without secret injection.
Common situations: New developer onboarding without the .env file; CI/CD pipeline missing secret bindings; a config copied from another project referencing vars that were never set.
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
- environment variable not found: %s
- error parsing environment variables: %s
- error converting config file: %s
- unable to parse YAML: %s
- document %d: %s
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/31186250da161eee.
Report an issue: GitHub.