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

  1. Check the wrapped cause: 'address already in use' means a live process owns the socket — stop it or wait for it to exit
  2. Remove the stale socket file at addr manually if no bus process is running (rm the socket path under the config dir)
  3. Ensure the socket's parent directory exists, is writable, and is owned by the current user
  4. 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

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


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/b311422fb648e0a9. Report an issue: GitHub.