larksuite/cli · error
bus listen: %w
Error message
bus listen: %w
What it means
Bus.Run in internal/event/bus/bus.go fails when the transport cannot bind the listen address for this app's event bus. After cleanup of a stale socket it retries transport.Listen once; if binding still fails the error is wrapped as "bus listen: %w" and returned, aborting bus startup. The cause is the underlying transport (e.g. Unix socket) error.
Source
Thrown at internal/event/bus/bus.go:108
b.logger.Printf("Another bus already holds %s/bus.alive.lock, exiting", eventsDir)
return nil
}
b.logger.Printf("[bus] pid file write failed: %v (status discovery may miss this bus)", pidErr)
} else {
b.pidHandle = pidHandle
}
ln, err := b.transport.Listen(addr)
if err != nil {
if probe, dialErr := b.transport.Dial(addr); dialErr == nil {
probe.Close()
b.logger.Printf("Another bus is already running for %s, exiting", b.appID)
return nil
}
b.transport.Cleanup(addr)
ln, err = b.transport.Listen(addr)
if err != nil {
return fmt.Errorf("bus listen: %w", err)
}
}
b.listener = ln
b.logger.Printf("Bus started for app=%s pid=%d addr=%s", b.appID, os.Getpid(), addr)
b.idleTimer = time.NewTimer(idleTimeout)
sourceCtx, sourceCancel := context.WithCancel(ctx)
defer sourceCancel()
b.startSources(sourceCtx)
acceptDone := make(chan struct{})
go func() {
defer close(acceptDone)
b.acceptLoop(ctx)
}()
// Re-check live conn count under lock: a stale idle tick can linger past a concurrent Stop+Reset.View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Check the wrapped cause: 'address already in use' means a live process owns the socket — stop it or wait for it to exit
- Remove the stale socket file at addr manually if no bus process is running (rm the socket path under the config dir)
- Ensure the socket's parent directory exists, is writable, and is owned by the current user
- Verify LARKSUITE_CLI_CONFIG_DIR points to a writable location; rerun the command
Defensive patterns
Strategy: retry
Validate before calling
if fi, err := os.Stat(socketDir); err != nil || !fi.IsDir() {
return fmt.Errorf("bus socket dir %s unavailable", socketDir)
} Type guard
func isListenError(err error) bool { return err != nil && strings.Contains(err.Error(), "bus listen:") } Try / catch
if err := bus.Run(ctx); err != nil {
var wrapped interface{ Unwrap() error }
if errors.As(err, &inner) && isAddrInUse(inner) {
// stop stale process or remove stale socket, then retry once
}
return err
} Prevention
- Ensure the bus socket directory exists and is writable by the current user
- Stop orphaned lark-cli processes that hold the socket before restarting
- Keep LARKSUITE_CLI_CONFIG_DIR on a stable writable path
- Rely on the library's Cleanup/retry-once path instead of removing sockets concurrently
When it happens
Trigger: Run() reaches transport.Listen(addr) and it returns an error: address already in use by a live foreign process, permission denied on the socket path/socket directory, socket directory missing, or path too long. This happens only when this process is not reusing an existing healthy bus (otherwise it exits early with nil).
Common situations: Another lark-cli process still holds the socket so Cleanup could not remove it; stale socket owned by a different user; LARKSUITE_CLI_CONFIG_DIR on a read-only or nonexistent path; container with a full or restricted tmp dir.
Related errors
- annotated_csv did not parse into the rows the server reporte
- lark-cli timed out after {timeout}s
- failed to parse user info: %w
- app registration failed: read body: %w
- app registration failed: HTTP %d – response not JSON
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/b311422fb648e0a9.
Report an issue: GitHub.