{"record":{"id":"b26e9121cbcd5461","repo":"googleapis/mcp-toolbox","slug":"error-parsing-environment-variables-s","errorCode":null,"errorMessage":"error parsing environment variables: %s","messagePattern":"error parsing environment variables: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/internal/config.go","lineNumber":193,"sourceCode":"\t\tif i >= index {\n\t\t\tbreak\n\t\t}\n\t\tif r == '\\n' {\n\t\t\tline++\n\t\t\tcolumn = 1\n\t\t} else {\n\t\t\tcolumn++\n\t\t}\n\t}\n\treturn line, column\n}\n\nfunc (p *ConfigParser) ParseConfig(ctx context.Context, raw []byte) (Config, error) {\n\tvar config Config\n\t// Replace environment variables if found\n\toutput, err := p.parseEnv(string(raw))\n\tif err != nil {\n\t\treturn config, fmt.Errorf(\"error parsing environment variables: %s\", err)\n\t}\n\traw = []byte(output)\n\n\traw, err = ConvertConfig(ctx, raw)\n\tif err != nil {\n\t\treturn config, fmt.Errorf(\"error converting config file: %s\", err)\n\t}\n\n\t// Parse contents\n\tconfig.Sources, config.AuthServices, config.EmbeddingModels, config.Tools, config.Prompts, config.Groups, err = server.UnmarshalPrimitiveConfig(ctx, raw)\n\tif err != nil {\n\t\treturn config, err\n\t}\n\treturn config, nil\n}\n\n// ConvertConfig converts configuration file to flat format and rewrites toolsets\n// to the group kind.","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/cmd/internal/config.go#L175-L211","documentation":"ParseConfig wraps any error from parseEnv (missing or failed environment variable substitution) with this message. It means the raw config YAML could not have its ${VAR} placeholders resolved, so parsing aborts before YAML decoding. The inner error names the missing variable(s) or the substitution failure.","triggerScenarios":"Loading a toolbox config whose ${VAR} placeholders reference unset environment variables, or whose substitution itself fails (e.g. malformed placeholder syntax), via LoadConfig or LoadAndMergeConfigs.","commonSituations":"Secrets not present in the deployment environment; wrong shell profile loaded; config templated for one environment and run in another; invalid placeholder syntax like ${VAR (unclosed).","solutions":["Read the wrapped inner message, export/provide the listed environment variables, and retry.","Fix malformed ${...} placeholder syntax in the config file.","Verify the intended environment (shell profile, CI secrets, k8s env) is actually the one in effect.","Run `toolbox --env-file .env` or equivalent to load variables from a file."],"exampleFix":"// before: config: url: ${API_URL}, API_URL unset\nConfig, err := parser.ParseConfig(ctx, raw) // \"error parsing environment variables: environment variable not found: API_URL\"\n// after\nos.Setenv(\"API_URL\", \"https://api.example.com\")\nConfig, err := parser.ParseConfig(ctx, raw) // succeeds","handlingStrategy":"try-catch","validationCode":"re := regexp.MustCompile(`\\$\\{[A-Za-z_][A-Za-z0-9_]*\\}`)\nfor _, m := range re.FindAllStringSubmatch(string(raw), -1) {\n    if os.Getenv(m[1]) == \"\" { return fmt.Errorf(\"missing env var %s\", m[1]) }\n}","typeGuard":null,"tryCatchPattern":"cfg, err := parser.ParseConfig(ctx, raw)\nif err != nil {\n    var envErr = \"error parsing environment variables\"\n    if strings.Contains(err.Error(), envErr) {\n        log.Fatalf(\"fix env vars for config load: %v\", err) // inner message names the var(s)\n    }\n}","preventionTips":["Run the placeholder regex preflight over configs in CI before deploying.","Use --env-file so variable loading is explicit and reproducible.","Keep placeholder syntax valid: ${VAR}, never unclosed braces."],"tags":["config","environment","env-var","startup","error-wrapping"],"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-08T10:18:20.063Z"}