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

  1. Export every variable listed in the error message (each ' - ' bullet) before starting.
  2. Provide all variables via --env-file or your platform's secret/environment injection.
  3. Fix variable-name mismatches between the config placeholders and the actual environment.
  4. 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

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


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/31186250da161eee. Report an issue: GitHub.