{"record":{"id":"63e5f2d5a2d73f32","repo":"matryer/xbar","slug":"load-json-file-vars","errorCode":null,"errorMessage":"load json file vars","messagePattern":"load json file vars","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/plugins/variables.go","lineNumber":88,"sourceCode":"\tvar wg sync.WaitGroup\n\tvar defaultVars, jsonFileVars map[string]interface{}\n\tvar defaultVarsErr, jsonFileVarsErr error\n\twg.Add(1)\n\tgo func() {\n\t\tdefaultVars, defaultVarsErr = p.loadVariablesFromPluginMetadata()\n\t\twg.Done()\n\t}()\n\twg.Add(1)\n\tgo func() {\n\t\tjsonFileVars, jsonFileVarsErr = p.loadVariablesFromJSONFile()\n\t\twg.Done()\n\t}()\n\twg.Wait()\n\tif defaultVarsErr != nil {\n\t\treturn nil, errors.Wrap(defaultVarsErr, \"load default vars\")\n\t}\n\tif jsonFileVarsErr != nil {\n\t\treturn nil, errors.Wrap(jsonFileVarsErr, \"load json file vars\")\n\t}\n\t// add the json file vars to the defaults,\n\t// and return them.\n\tfor k, v := range jsonFileVars {\n\t\tdefaultVars[k] = v\n\t}\n\treturn defaultVars, nil\n}\n\n// loadVariablesFromJSONFile gets a list of environment variable friendly\n// key=value pairs.\nfunc (p *Plugin) loadVariablesFromJSONFile() (map[string]interface{}, error) {\n\tvariablesJSONFilename := p.Command + variableJSONFileExt\n\tf, err := os.Open(variablesJSONFilename)\n\tif err != nil && os.IsNotExist(err) {\n\t\t// no .vars.json file - no probs\n\t\treturn nil, nil\n\t} else if err != nil {","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/matryer/xbar/blob/d624239058997c80118eaebe2e7f8331b3c765e0/pkg/plugins/variables.go#L70-L106","documentation":"loadVariables (pkg/plugins/variables.go:87-88) wraps errors from loadVariablesFromJSONFile with 'load json file vars'. The plugin's .vars.json file (p.Command + '.vars.json') exists but could not be opened or its JSON could not be parsed, so user-saved variable overrides are unavailable. Missing files are fine (treated as empty), so this error always means a present-but-broken file.","triggerScenarios":"The .vars.json file exists but has invalid JSON (hand-edited, truncated); the file is unreadable due to permissions or is actually a directory; open fails with an error other than IsNotExist at pkg/plugins/variables.go:107.","commonSituations":"User edits the .vars.json in a text editor and breaks the JSON; interrupted save leaves a truncated file; sync tools replace the file with a placeholder; file owned by root after running as sudo once.","solutions":["Validate and fix the JSON in <plugin>.vars.json with a linter/editor.","Delete the broken .vars.json file — it is optional, and it will be recreated on next save.","Check file permissions/ownership (chmod 600, chown to your user).","If it is a directory or placeholder, remove it and re-save variables via the plugin settings UI."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"varsPath := p.Command + \".vars.json\"\nif b, err := os.ReadFile(varsPath); err == nil {\n\tvar v map[string]interface{}\n\tif jerr := json.Unmarshal(b, &v); jerr != nil {\n\t\tlog.Printf(\"%s is not valid JSON, overrides will be ignored: %v\", varsPath, jerr)\n\t}\n}","typeGuard":null,"tryCatchPattern":"vars, err := p.loadVariables()\nif err != nil && strings.Contains(err.Error(), \"load json file vars\") {\n\tlog.Printf(\"ignoring broken vars override file: %+v\", err)\n\tos.Remove(p.Command + \".vars.json\")\n\tvars, err = p.loadVariablesFromPluginMetadata() // fall back to defaults\n}","preventionTips":["Edit .vars.json only with a JSON-aware editor and validate afterwards.","Treat the vars file as a cache: it is safe to delete and recreate.","Write it atomically on save to avoid truncated files.","Exclude *.vars.json from tools that may replace files with placeholders."],"tags":["go","json","plugins","corrupt-file"],"backgroundTag":"json-parse-error","analyzedSha":"d624239058997c80118eaebe2e7f8331b3c765e0","analyzedAt":"2026-09-02T22:38:22.007Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}