matryer/xbar · error
open plugin source
Error message
open plugin source
What it means
loadVariablesFromPluginMetadata (pkg/plugins/variables.go:123-125) wraps os.Open failures on the plugin executable itself (p.Command) with 'open plugin source'. The library reads the plugin's source to parse `<xbar.var>` default variable declarations, so if the executable cannot be opened, defaults cannot be loaded and the error propagates up through loadVariables ('load default vars').
Source
Thrown at pkg/plugins/variables.go:125
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")
}
defer pluginFile.Close()
pluginFileB, err := io.ReadAll(io.LimitReader(pluginFile, 1_000_000))
if err != nil {
return nil, errors.Wrap(err, "read plugin source")
}
pluginMetadata, err := metadata.Parse(metadata.DebugFunc(p.Debugf), p.CleanFilename(), string(pluginFileB))
if err != nil {
return nil, errors.Wrap(err, "metadata.Parse")
}
vars := make(map[string]interface{})
for _, pluginVar := range pluginMetadata.Vars {
if pluginVar.Default == "" {
// skip values with no default
continue
}
vars[pluginVar.Name] = pluginVar.DefaultValue()
}View on GitHub (pinned to d624239058)
Solutions
- Verify the path in p.Command exists and is readable: `ls -l <path>`; reinstall the plugin if missing.
- Restore read/execute permissions on the plugin file (chmod +rx).
- Update or remove the stale plugin entry so xbar stops referencing the old path.
- Refresh the plugin list in xbar (refresh menu) so p.Command is re-resolved from the actual installed location.
Example fix
// before
pluginFile, err := os.Open(p.Command)
if err != nil {
return nil, errors.Wrap(err, "open plugin source")
}
// after — guard at call site before loading vars
if _, err := os.Stat(p.Command); err != nil {
return nil, nil // plugin gone; no defaults to load
}
pluginFile, err := os.Open(p.Command)
if err != nil {
return nil, errors.Wrap(err, "open plugin source")
} Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(p.Command)
if err != nil {
log.Printf("plugin source %s missing: %v", p.Command, err)
} else if info.IsDir() {
log.Printf("plugin source %s is a directory", p.Command)
} else if info.Mode().Perm()&0444 == 0 {
log.Printf("plugin source %s is not readable", p.Command)
} Try / catch
if _, err := os.Stat(p.Command); err != nil {
log.Printf("skipping plugin: source not found: %v", err)
return nil // do not attempt to run or load vars
}
if err := p.run(); err != nil {
if strings.Contains(err.Error(), "open plugin source") {
log.Printf("plugin source unreadable, reinstall the plugin: %+v", err)
}
} Prevention
- Reinstall plugins through the app rather than moving files manually.
- Refresh the plugin list after updates so p.Command paths stay current.
- Check read/execute permissions when installing plugins from archives.
- Clean up uninstall leftovers so stale paths are not referenced.
When it happens
Trigger: The plugin binary/script was deleted, renamed, or moved after its variables were configured; p.Command contains a stale absolute path (plugin dir moved, e.g. ~/Library/Application Support/xbar changed); permission denied on the executable; running with a working directory where a relative p.Command no longer resolves.
Common situations: User updates a plugin (file replaced/removed) while xbar still holds the old path; plugin installed from another user's home directory lacks read permission; plugin uninstalled but xbar tries to rebuild env vars from a stale entry.
Related errors
AI-assisted analysis of matryer/xbar@d624239058 (2026-09-02).
Data as JSON: /api/errors/8a3c8a5c5566e920.
Report an issue: GitHub.