matryer/xbar · error
json.Unmarshal
Error message
json.Unmarshal
What it means
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.
Source
Thrown at pkg/plugins/variables.go:52
func LoadVariableValues(pluginDir, installedPluginPath string) (map[string]interface{}, error) {
filename := filepath.Join(pluginDir, installedPluginPath+variableJSONFileExt)
f, err := os.Open(filename)
if err != nil {
if os.IsNotExist(err) {
// no file - but not an error, just empty map
return map[string]interface{}{}, nil
}
return nil, errors.Wrap(err, "Open")
}
defer f.Close()
b, err := io.ReadAll(io.LimitReader(f, 1_000_000 /* ~1MB */))
if err != nil {
return nil, errors.Wrap(err, "ReadAll")
}
var values map[string]interface{}
err = json.Unmarshal(b, &values)
if err != nil {
return nil, errors.Wrap(err, "json.Unmarshal")
}
return values, nil
}
func (p *Plugin) loadVariablesAsEnvVars() ([]string, error) {
vars, err := p.loadVariables()
if err != nil {
return nil, errors.Wrap(err, "loadVariables")
}
envvars := make([]string, 0, len(vars))
for k, v := range vars {
envvars = append(envvars, fmt.Sprintf("%s=%v", k, v))
}
return envvars, nil
}
func (p *Plugin) loadVariables() (map[string]interface{}, error) {
var wg sync.WaitGroupView on GitHub (pinned to d624239058)
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.
Example fix
// before — in-place write, vulnerable to truncation
ioutil.WriteFile(filename, b, 0666)
// after — atomic write
if err := ioutil.WriteFile(filename+".tmp", b, 0666); err != nil {
return errors.Wrap(err, "WriteFile")
}
if err := os.Rename(filename+".tmp", filename); err != nil {
return errors.Wrap(err, "Rename")
} Defensive patterns
Strategy: validation
Validate before calling
path := filepath.Join(pluginDir, installedPluginPath+".vars.json")
b, err := os.ReadFile(path)
if err == nil {
var v map[string]interface{}
if err := json.Unmarshal(b, &v); err != nil {
log.Printf("vars file corrupt, will reset: %v", err)
os.Remove(path) // let the app recreate it
}
} Try / catch
values, err := plugins.LoadVariableValues(pluginDir, installedPluginPath)
if err != nil && strings.Contains(err.Error(), "json.Unmarshal") {
log.Printf("corrupt vars file, resetting: %v", err)
os.Remove(filepath.Join(pluginDir, installedPluginPath+".vars.json"))
values = map[string]interface{}{}
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
AI-assisted analysis of matryer/xbar@d624239058 (2026-09-02).
Data as JSON: /api/errors/29f0be6a3c6f4ec0.
Report an issue: GitHub.