{"record":{"id":"29f0be6a3c6f4ec0","repo":"matryer/xbar","slug":"json-unmarshal","errorCode":null,"errorMessage":"json.Unmarshal","messagePattern":"json\\.Unmarshal","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/plugins/variables.go","lineNumber":52,"sourceCode":"func LoadVariableValues(pluginDir, installedPluginPath string) (map[string]interface{}, error) {\n\tfilename := filepath.Join(pluginDir, installedPluginPath+variableJSONFileExt)\n\tf, err := os.Open(filename)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\t// no file - but not an error, just empty map\n\t\t\treturn map[string]interface{}{}, nil\n\t\t}\n\t\treturn nil, errors.Wrap(err, \"Open\")\n\t}\n\tdefer f.Close()\n\tb, err := io.ReadAll(io.LimitReader(f, 1_000_000 /* ~1MB */))\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"ReadAll\")\n\t}\n\tvar values map[string]interface{}\n\terr = json.Unmarshal(b, &values)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"json.Unmarshal\")\n\t}\n\treturn values, nil\n}\n\nfunc (p *Plugin) loadVariablesAsEnvVars() ([]string, error) {\n\tvars, err := p.loadVariables()\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"loadVariables\")\n\t}\n\tenvvars := make([]string, 0, len(vars))\n\tfor k, v := range vars {\n\t\tenvvars = append(envvars, fmt.Sprintf(\"%s=%v\", k, v))\n\t}\n\treturn envvars, nil\n}\n\nfunc (p *Plugin) loadVariables() (map[string]interface{}, error) {\n\tvar wg sync.WaitGroup","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/matryer/xbar/blob/d624239058997c80118eaebe2e7f8331b3c765e0/pkg/plugins/variables.go#L34-L70","documentation":"LoadVariableValues (pkg/plugins/variables.go:50-52) wraps json.Unmarshal failures with 'json.Unmarshal'. The .vars.json content is not a valid JSON object (JSON body must decode into map[string]interface{}), so the plugin's saved variables cannot be loaded. The wrapped error includes the exact byte offset and parse problem.","triggerScenarios":"The vars file was hand-edited with invalid JSON; a previous save was interrupted/corrupted (partial write, disk full); the file contains an array, string, or null instead of an object; encoding issues (BOM, non-UTF8 bytes).","commonSituations":"Users edit the .vars.json file with a text editor and leave a trailing comma or quotes mismatched; crash during WriteFile leaves a truncated file; another tool writes a different format to the same path.","solutions":["Open the .vars.json file in a JSON validator/linter and fix the syntax error (commonly trailing commas or missing quotes).","Delete the corrupt file so LoadVariableValues returns an empty map and re-save variables from the plugin settings UI.","Restore the file from backup if it was truncated by an interrupted write.","Ensure the value saved is a JSON object (map), not an array or scalar.","Upgrade code paths that write the file to write to a temp file and rename atomically to avoid corruption."],"exampleFix":"// before — in-place write, vulnerable to truncation\nioutil.WriteFile(filename, b, 0666)\n// after — atomic write\nif err := ioutil.WriteFile(filename+\".tmp\", b, 0666); err != nil {\n\treturn errors.Wrap(err, \"WriteFile\")\n}\nif err := os.Rename(filename+\".tmp\", filename); err != nil {\n\treturn errors.Wrap(err, \"Rename\")\n}","handlingStrategy":"validation","validationCode":"path := filepath.Join(pluginDir, installedPluginPath+\".vars.json\")\nb, err := os.ReadFile(path)\nif err == nil {\n\tvar v map[string]interface{}\n\tif err := json.Unmarshal(b, &v); err != nil {\n\t\tlog.Printf(\"vars file corrupt, will reset: %v\", err)\n\t\tos.Remove(path) // let the app recreate it\n\t}\n}","typeGuard":null,"tryCatchPattern":"values, err := plugins.LoadVariableValues(pluginDir, installedPluginPath)\nif err != nil && strings.Contains(err.Error(), \"json.Unmarshal\") {\n\tlog.Printf(\"corrupt vars file, resetting: %v\", err)\n\tos.Remove(filepath.Join(pluginDir, installedPluginPath+\".vars.json\"))\n\tvalues = map[string]interface{}{}\n}","preventionTips":["Validate JSON in an editor/linter before saving .vars.json by hand.","Write the file atomically (temp file + os.Rename) to prevent truncation on crash/disk-full.","Never put a BOM in the file; save as plain UTF-8.","Always ensure the saved top-level value is a JSON object (map), not an array."],"tags":["go","json","parse","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"}