{"record":{"id":"db93ad03d1ef4d80","repo":"larksuite/cli","slug":"busdiscover-read-events-dir-w","errorCode":null,"errorMessage":"busdiscover: read events dir: %w","messagePattern":"busdiscover: read events dir: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/event/adapter/localbus/busdiscover/pidfile.go","lineNumber":108,"sourceCode":"\terr := probe.TryLock()\n\tif errors.Is(err, lockfile.ErrHeld) {\n\t\treturn true\n\t}\n\tif err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"[busdiscover] probe %s: %v\\n\", lockPath, err) //nolint:forbidigo // internal diagnostic; scanner has no IOStreams plumbing\n\t\treturn false\n\t}\n\t_ = probe.Unlock()\n\treturn false\n}\n\nfunc scanLiveBuses(eventsDir string) ([]Process, error) {\n\tentries, err := vfs.ReadDir(eventsDir)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn nil, nil\n\t\t}\n\t\treturn nil, fmt.Errorf(\"busdiscover: read events dir: %w\", err)\n\t}\n\tvar result []Process\n\tfor _, e := range entries {\n\t\tif !e.IsDir() {\n\t\t\tcontinue\n\t\t}\n\t\tappID := e.Name()\n\t\tappDir := filepath.Join(eventsDir, appID)\n\t\tif !isBusAlive(appDir) {\n\t\t\tcontinue\n\t\t}\n\t\tpid, startTime, err := readPIDFile(appDir)\n\t\tif err != nil {\n\t\t\tfmt.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\n\t\t\tresult = append(result, Process{PID: 0, AppID: appID})\n\t\t\tcontinue\n\t\t}\n\t\tresult = append(result, Process{PID: pid, AppID: appID, StartTime: startTime})","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/event/adapter/localbus/busdiscover/pidfile.go#L90-L126","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: events path is a regular file\n$ file ~/.lark/events  -> ~/.lark/events: ASCII text\n$ rm ~/.lark/events   # let the CLI recreate it as a directory\n// after: directory with sane perms\n$ mkdir -p ~/.lark/events && chmod 755 ~/.lark/events","handlingStrategy":"try-catch","validationCode":"info, err := os.Stat(eventsDir)\nif err != nil || !info.IsDir() {\n\t// path missing or not a directory — fix permissions or recreate before scanning\n}\n// also check readability: f, err := os.Open(eventsDir); f.Close()","typeGuard":null,"tryCatchPattern":"procs, err := busdiscover.ScanBusProcesses(appDir)\nvar pe *fs.PathError\nif err != nil {\n\tif errors.As(err, &pe) && pe.Op == \"open\" {\n\t\t// permission/path problem: report eventsDir, suggest chown/chmod\n\t} else {\n\t\treturn fmt.Errorf(\"scan failed: %w\", err)\n\t}\n}","preventionTips":["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"],"tags":["go","localbus","filesystem","permissions","readdir"],"backgroundTag":"directory-read-failed","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}