{"record":{"id":"0a9958c4bf340bf5","repo":"matryer/xbar","slug":"readall","errorCode":null,"errorMessage":"ReadAll","messagePattern":"ReadAll","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/plugins/variables.go","lineNumber":47,"sourceCode":"\t}\n\treturn nil\n}\n\n// LoadVariableValues loads the variables for a plugin.\nfunc 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}","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/matryer/xbar/blob/d624239058997c80118eaebe2e7f8331b3c765e0/pkg/plugins/variables.go#L29-L65","documentation":"LoadVariableValues (pkg/plugins/variables.go:45-47) wraps io.ReadAll failures with 'ReadAll'. After the file opens successfully, reading up to 1MB can still fail on underlying I/O errors (bad sectors, interrupted read on network mounts). The wrapped OS error is reported as 'ReadAll: <os error>'.","triggerScenarios":"Reading the .vars.json file from a network volume that drops mid-read; hardware/disk I/O error; file truncated or locked by another process during read.","commonSituations":"Plugin directory on NFS/SMB that times out; failing disk; container volume unmounted while xbar runs.","solutions":["Retry LoadVariableValues after checking the mount/filesystem health.","Run filesystem checks (fsck) if I/O errors persist on local disks.","Move the plugin directory onto a local disk instead of a network share.","Check dmesg/system logs for the underlying I/O error to identify hardware vs. network causes."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"path := filepath.Join(pluginDir, installedPluginPath+\".vars.json\")\nif f, err := os.Open(path); err == nil {\n\tdefer f.Close()\n\tif _, err := f.Read(make([]byte, 1)); err != nil {\n\t\tlog.Printf(\"vars file unreadable (io): %v\", err)\n\t}\n}","typeGuard":null,"tryCatchPattern":"var values map[string]interface{}\nfor attempt := 0; attempt < 3; attempt++ {\n\tvalues, err = plugins.LoadVariableValues(pluginDir, installedPluginPath)\n\tif err == nil {\n\t\tbreak\n\t}\n\tif strings.Contains(err.Error(), \"ReadAll\") {\n\t\ttime.Sleep(time.Duration(attempt+1) * 100 * time.Millisecond)\n\t\tcontinue\n\t}\n\treturn err\n}","preventionTips":["Keep the plugin directory on local storage, not NFS/SMB.","Check dmesg for disk errors if ReadAll failures recur.","Retry transient I/O errors with backoff before giving up.","Back up *.vars.json files so data loss from failing disks is recoverable."],"tags":["go","filesystem","io","read"],"backgroundTag":"disk-io-error","analyzedSha":"d624239058997c80118eaebe2e7f8331b3c765e0","analyzedAt":"2026-09-02T22:38:22.007Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}