larksuite/cli · error
busdiscover: read events dir: %w
Error message
busdiscover: read events dir: %w
What it means
scanLiveBuses wraps any error from vfs.ReadDir on the events directory (other than NotExist, which is treated as zero buses). This means the directory exists but could not be read — permission denial, I/O error, or path-not-a-directory.
Source
Thrown at internal/event/adapter/localbus/busdiscover/pidfile.go:108
err := probe.TryLock()
if errors.Is(err, lockfile.ErrHeld) {
return true
}
if err != nil {
fmt.Fprintf(os.Stderr, "[busdiscover] probe %s: %v\n", lockPath, err) //nolint:forbidigo // internal diagnostic; scanner has no IOStreams plumbing
return false
}
_ = probe.Unlock()
return false
}
func scanLiveBuses(eventsDir string) ([]Process, error) {
entries, err := vfs.ReadDir(eventsDir)
if err != nil {
if os.IsNotExist(err) {
return nil, nil
}
return nil, fmt.Errorf("busdiscover: read events dir: %w", err)
}
var result []Process
for _, e := range entries {
if !e.IsDir() {
continue
}
appID := e.Name()
appDir := filepath.Join(eventsDir, appID)
if !isBusAlive(appDir) {
continue
}
pid, startTime, err := readPIDFile(appDir)
if err != nil {
fmt.Fprintf(os.Stderr, "[busdiscover] live bus at %s but pid file unreadable: %v\n", appDir, err) //nolint:forbidigo // internal diagnostic; scanner has no IOStreams plumbing
result = append(result, Process{PID: 0, AppID: appID})
continue
}
result = append(result, Process{PID: pid, AppID: appID, StartTime: startTime})View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Check permissions: the scanning process needs read+execute on the events directory (ls -ld <eventsDir>; chown/chmod as needed)
- Verify the path is actually a directory (file eventsDir); if it is a file, remove it so it can be recreated as a directory
- Check filesystem health/mount status (dmesg, mount output) if I/O errors appear
- Ensure the app dir/state dir env pointing at the events dir is correct and not overridden to an unusable path
Example fix
// before: events path is a regular file $ file ~/.lark/events -> ~/.lark/events: ASCII text $ rm ~/.lark/events # let the CLI recreate it as a directory // after: directory with sane perms $ mkdir -p ~/.lark/events && chmod 755 ~/.lark/events
Defensive patterns
Strategy: try-catch
Validate before calling
info, err := os.Stat(eventsDir)
if err != nil || !info.IsDir() {
// path missing or not a directory — fix permissions or recreate before scanning
}
// also check readability: f, err := os.Open(eventsDir); f.Close() Try / catch
procs, err := busdiscover.ScanBusProcesses(appDir)
var pe *fs.PathError
if err != nil {
if errors.As(err, &pe) && pe.Op == "open" {
// permission/path problem: report eventsDir, suggest chown/chmod
} else {
return fmt.Errorf("scan failed: %w", err)
}
} Prevention
- Run the CLI and bus under the same user or group with shared state-dir permissions
- Never replace the events directory with a file or symlink to a file
- Include the eventsDir path in monitoring for permission changes after container/VM restarts
- Treat NotExist as healthy (the library already does) — only alert on other ReadDir errors
When it happens
Trigger: Calling ScanBusProcesses (or the tests) when eventsDir exists but ReadDir fails with a non-ENOENT error: e.g. the path is a regular file instead of a directory, or the process lacks read permission on it.
Common situations: LARKSUITE_CLI config/state dir owned by another user or restrictive umask; events path accidentally created as a file by a buggy earlier version; read-only or corrupted filesystem; container volume mounted with wrong permissions.
Related errors
- busdiscover: mkdir %s: %w
- busdiscover: write pid tmp: %w
- busdiscover: rename pid file: %w
- cannot inspect path: %w
- invalid chart size: {size!r}
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/db93ad03d1ef4d80.
Report an issue: GitHub.