{"record":{"id":"567e1fc694fd5f5f","repo":"glanceapp/glance","slug":"parsing-variable-v","errorCode":null,"errorMessage":"parsing variable: %v","messagePattern":"parsing variable: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/glance/config.go","lineNumber":171,"sourceCode":"\t\t\t// in the regex has been changed without updating the below code\n\t\t\treturn match\n\t\t}\n\n\t\tprefix := string(groups[1])\n\t\tif prefix == `\\` {\n\t\t\tif len(match) >= 2 {\n\t\t\t\treturn match[1:]\n\t\t\t} else {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\n\t\ttypeAsString, variableName := string(groups[2]), string(groups[3])\n\t\tvariableType := ternary(typeAsString == \"\", configVarTypeEnv, typeAsString)\n\n\t\tparsedValue, returnOriginal, localErr := parseConfigVariableOfType(variableType, variableName)\n\t\tif localErr != nil {\n\t\t\terr = fmt.Errorf(\"parsing variable: %v\", localErr)\n\t\t\treturn nil\n\t\t}\n\n\t\tif returnOriginal {\n\t\t\treturn match\n\t\t}\n\n\t\treturn []byte(prefix + parsedValue)\n\t})\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn replaced, nil\n}\n\n// When the bool return value is true, it indicates that the caller should use the original value","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/glanceapp/glance/blob/91324e8de762702e97b0ac5c8e36271d644d8642/internal/glance/config.go#L153-L189","documentation":"Wraps any lower-level failure from parseConfigVariableOfType while expanding {{...}} variable references in glance.yml. The config loader regex-replaces variable expressions; if resolving a variable (env, secret, file-from-env) returns an error, it is wrapped as 'parsing variable: <cause>' and the whole config parse fails. The message deliberately prefixes context but keeps the inner error (e.g. 'environment variable FOO not found').","triggerScenarios":"Any {{ env.FOO }}, {{ secret.foo }}, or {{ file-from-env.FOO }} expression in glance.yml whose resolution fails: missing env var, unreadable /run/secrets file, or file-from-env path problems. The outer regex match groups determine variableType and variableName passed to the resolver.","commonSituations":"Deploying to an environment missing variables referenced in the config template; Docker secrets not mounted at /run/secrets; typo'd variable names after refactor; renaming env vars without updating glance.yml.","solutions":["Read the inner error after 'parsing variable: ' — it names the exact variable and cause (env not found, secret read failure, etc.).","Export the missing environment variable or fix its name in the {{ env.X }} expression.","For {{ secret.X }}, ensure /run/secrets/X exists and is readable by the Glance process.","For {{ file-from-env.X }}, set X and verify the path it points to.","Note: only expressions whose name matches envVariableNamePattern are resolved; non-matching env names are left as-is, so check the pattern if the value isn't substituted."],"exampleFix":"# before: APP_TOKEN not exported\n$ glance --config glance.yml\n# error: parsing variable: environment variable APP_TOKEN not found\n\n# after\n$ export APP_TOKEN=...\n$ glance --config glance.yml","handlingStrategy":"try-catch","validationCode":"# Expand-and-check before starting Glance\nfor var in $(grep -oE '\\{\\{ *env\\.[A-Za-z_][A-Za-z0-9_]* *\\}\\}' glance.yml | sed -E 's/.*env\\.([A-Za-z0-9_]+).*/\\1/'); do\n  [ -n \"${!var}\" ] || { echo \"missing env var: $var\"; exit 1; }\ndone","typeGuard":null,"tryCatchPattern":"// Running config programmatically (custom tooling):\nerr := cfg.Parse()\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"parsing variable: \") {\n        cause := strings.TrimPrefix(err.Error(), \"parsing variable: \")\n        // cause names the variable and stage: env lookup, secret read, file read\n        log.Fatalf(\"config variable problem: %s\", cause)\n    }\n}","preventionTips":["Keep a checklist of every {{ env.* }}/{{ secret.* }}/{{ file-from-env.* }} referenced in glance.yml and assert them in deploy scripts.","Run `glance config:validate` in the target environment, not just locally."],"tags":["config","variables","environment","secrets"],"backgroundTag":null,"analyzedSha":"91324e8de762702e97b0ac5c8e36271d644d8642","analyzedAt":"2026-08-15T14:12:54.279Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}