matryer/xbar · error
read plugin source
Error message
read plugin source
What it means
This error is wrapped by loadVariablesFromPluginMetadata when io.ReadAll fails while reading the opened plugin file's contents (capped at 1MB via io.LimitReader). It means the plugin file was successfully opened but its bytes could not be read from disk (I/O failure after open). The library wraps the underlying OS error so callers know the failure occurred at the read-plugin-source step of variable extraction.
Source
Thrown at pkg/plugins/variables.go:130
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()
}
return vars, nil
}
View on GitHub (pinned to d624239058)
Solutions
- Check the wrapped cause (%+v of the error) for the underlying errno (EIO, ESTALE, EACCES) and fix the filesystem/permission issue
- Re-download or reinstall the plugin file — it is likely corrupted, truncated, or missing
- Verify the plugin path points to a regular readable file (os.Stat + Mode().IsRegular()) before loading
- Move plugin files off network/unstable mounts to local disk
- Rerun the load; transient I/O errors may not recur
Example fix
// before
pluginFileB, err := io.ReadAll(io.LimitReader(pluginFile, 1_000_000))
if err != nil {
return nil, errors.Wrap(err, "read plugin source")
}
// after
if fi, statErr := os.Stat(path); statErr != nil || !fi.Mode().IsRegular() {
return nil, fmt.Errorf("plugin %s is not a regular file", path)
}
pluginFileB, err := io.ReadAll(io.LimitReader(pluginFile, 1_000_000))
if err != nil {
return nil, errors.Wrap(err, "read plugin source")
} Defensive patterns
Strategy: validation
Validate before calling
func pluginReadable(path string) error {
fi, err := os.Stat(path)
if err != nil {
return err
}
if !fi.Mode().IsRegular() {
return fmt.Errorf("%s is not a regular file", path)
}
f, err := os.Open(path)
if err != nil {
return err
}
f.Close()
return nil
} Try / catch
vars, err := loadVariablesFromPluginMetadata(p)
if err != nil {
if strings.Contains(fmt.Sprintf("%+v", err), "read plugin source") {
log.Printf("plugin file unreadable, skipping: %v", err)
return defaultVars, nil
}
return nil, err
} Prevention
- Stat the plugin path and confirm it is a regular, readable file before loading
- Store plugins on local, stable storage rather than network mounts
- Never mutate or delete plugin files while the application is loading them
- Log errors with %+v to surface the wrapped errno for diagnosis
When it happens
Trigger: os.Open succeeded on pkg/plugins file (pkg/plugins/variables.go:130) but io.ReadAll(io.LimitReader(pluginFile, 1_000_000)) returned a non-nil error — e.g. file deleted/truncated between open and read, disk I/O error, read permission revoked mid-read, or a device/FIFO that errors on read.
Common situations: Plugin binary replaced or removed while the app loads variables from it; network-mounted plugin directory with flaky connectivity; filesystem errors (bad sectors, EIO); plugin file is a special device that fails on read; SELinux/AppArmor denying read after open.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
AI-assisted analysis of matryer/xbar@d624239058 (2026-09-02).
Data as JSON: /api/errors/629cb4fff035058d.
Report an issue: GitHub.