{"record":{"id":"31186250da161eee","repo":"googleapis/mcp-toolbox","slug":"environment-variables-not-found-s","errorCode":null,"errorMessage":"environment variables not found:\n  - %s","messagePattern":"environment variables not found:\n  - (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/internal/config.go","lineNumber":146,"sourceCode":"\t\tlastIndex = end\n\t}\n\toutput.WriteString(input[lastIndex:])\n\n\t// Filter out OptionalEnvVars that were also found as required\n\tvar finalOptional []string\n\tfor _, v := range p.OptionalEnvVars {\n\t\tif !slices.Contains(p.requiredEnvVars, v) && !slices.Contains(finalOptional, v) {\n\t\t\tfinalOptional = append(finalOptional, v)\n\t\t}\n\t}\n\tp.OptionalEnvVars = finalOptional\n\n\tvar err error\n\tif len(missing) > 0 {\n\t\tif len(missing) == 1 {\n\t\t\terr = fmt.Errorf(\"environment variable not found: %s\", missing[0])\n\t\t} else {\n\t\t\terr = fmt.Errorf(\"environment variables not found:\\n  - %s\", strings.Join(missing, \"\\n  - \"))\n\t\t}\n\t}\n\n\treturn output.String(), err\n}\n\n// isInsideComment checks if the given 1-based rune offset in the YAML input is\n// within a comment token. Token positions from the lexer are 1-based rune\n// offsets, so callers must convert byte offsets before calling this.\nfunc isInsideComment(tokens token.Tokens, runeOffset int) bool {\n\tfor _, t := range tokens {\n\t\tif t.Type == token.CommentType && t.Position != nil {\n\t\t\t// Position.Offset points at the \"#\", but Origin also carries any\n\t\t\t// indentation that precedes it, so measure the length from the \"#\".\n\t\t\tlength := utf8.RuneCountInString(strings.TrimLeft(t.Origin, \" \\t\"))\n\t\t\tif runeOffset >= t.Position.Offset && runeOffset < t.Position.Offset+length {\n\t\t\t\treturn true\n\t\t\t}","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/cmd/internal/config.go#L128-L164","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before: \"environment variables not found:\\n  - DB_USER\\n  - DB_PASSWORD\"\n./toolbox --config tools.yaml\n# after\nexport DB_USER=\"app\" DB_PASSWORD=\"secret\"\n./toolbox --config tools.yaml","handlingStrategy":"validation","validationCode":"for _, v := range []string{\"DB_USER\", \"DB_PASSWORD\", \"DB_HOST\"} {\n    if os.Getenv(v) == \"\" { log.Fatalf(\"missing env var: %s\", v) }\n}","typeGuard":null,"tryCatchPattern":"if strings.HasPrefix(err.Error(), \"environment variables not found:\") {\n    log.Fatalf(\"export each listed variable, or provide --env-file: %v\", err)\n}","preventionTips":["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."],"tags":["config","environment","env-var","startup"],"backgroundTag":"missing-env-var","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}