matryer/xbar · error
open vars json file
Error message
open vars json file
What it means
loadVariablesFromJSONFile (pkg/plugins/variables.go:102-107) opens <plugin.Command>.vars.json. A missing file is deliberately ignored (returns nil, nil), but any other os.Open error is wrapped as 'open vars json file'. This means the vars file exists but is inaccessible — e.g. permission denied, path is a directory, or too many open files.
Source
Thrown at pkg/plugins/variables.go:107
}
// add the json file vars to the defaults,
// and return them.
for k, v := range jsonFileVars {
defaultVars[k] = v
}
return defaultVars, nil
}
// loadVariablesFromJSONFile gets a list of environment variable friendly
// key=value pairs.
func (p *Plugin) loadVariablesFromJSONFile() (map[string]interface{}, error) {
variablesJSONFilename := p.Command + variableJSONFileExt
f, err := os.Open(variablesJSONFilename)
if err != nil && os.IsNotExist(err) {
// no .vars.json file - no probs
return nil, nil
} else if err != nil {
return nil, errors.Wrap(err, "open vars json file")
}
defer f.Close()
b, err := io.ReadAll(io.LimitReader(f, 1_000_000))
if err != nil {
return nil, err
}
var vars map[string]interface{}
if err := json.Unmarshal(b, &vars); err != nil {
return nil, errors.Wrap(err, "json.Unmarshal")
}
return vars, nil
}
func (p *Plugin) loadVariablesFromPluginMetadata() (map[string]interface{}, error) {
// read the plugin metadata for default values
pluginFile, err := os.Open(p.Command)
if err != nil {
return nil, errors.Wrap(err, "open plugin source")View on GitHub (pinned to d624239058)
Solutions
- Inspect the file: `ls -la <plugin>.vars.json` — check it is a regular file with read permission.
- Fix permissions/ownership or remove a directory/placeholder at that path.
- Raise the open-file limit (ulimit -n) if many plugins load at once.
- Check audit logs / use errors %+v to see the exact errno behind the wrapper.
Defensive patterns
Strategy: try-catch
Validate before calling
varsPath := p.Command + ".vars.json"
if info, err := os.Stat(varsPath); err == nil {
if !info.Mode().IsRegular() {
log.Printf("%s is not a regular file", varsPath)
}
if info.Mode().Perm()&0400 == 0 {
log.Printf("%s not readable", varsPath)
}
} Try / catch
vars, err := p.loadVariables()
if err != nil {
var se syscall.Errno
if errors.As(errors.Cause(err), &se) && errors.Is(se, syscall.EMFILE) {
log.Printf("too many open files while loading vars: %v", err)
}
return nil, err
} Prevention
- Raise ulimit -n / RLIMIT_NOFILE if xbar runs many plugins concurrently.
- Remove directory placeholders masquerading as .vars.json files.
- Normalize ownership/permissions of the plugins directory after restores.
- Audit broken symlinks in the plugin dir periodically.
When it happens
Trigger: Permission denied on the .vars.json or a parent directory; the path resolves to a directory; a broken symlink; EMFILE (too many open files) when many plugins load concurrently; I/O error on the underlying storage.
Common situations: xbar runs with many plugins simultaneously and hits the open-file limit; backup/sync placeholder directories named *.vars.json; file created by another user (root) with restrictive mode.
Related errors
- Open
- create directory %s for plugin
- create plugin file %s
- set executable permission on plugin entry point
- ReadDir
AI-assisted analysis of matryer/xbar@d624239058 (2026-09-02).
Data as JSON: /api/errors/e73d300f932d8b7c.
Report an issue: GitHub.