chenhg5/cc-connect · error

webex: platform stopped

Error message

webex: platform stopped

What it means

Start refuses to begin if the platform is already shutting down (p.stopping is set under the mutex). This prevents resurrecting a platform after Stop was called. It is a lifecycle state guard, not a network error.

Source

Thrown at platform/webex/webex.go:202

func (p *Platform) isStopping() bool {
	p.mu.RLock()
	defer p.mu.RUnlock()
	return p.stopping
}

const (
	initialBackoff   = time.Second
	maxBackoff       = 30 * time.Second
	stableConnWindow = 10 * time.Second
)

// Start fetches the bot identity, registers a device, and launches the
// reconnecting WebSocket read loop in the background.
func (p *Platform) Start(handler core.MessageHandler) error {
	p.mu.Lock()
	if p.stopping {
		p.mu.Unlock()
		return fmt.Errorf("webex: platform stopped")
	}
	p.handler = handler
	ctx, cancel := context.WithCancel(context.Background())
	p.cancel = cancel
	p.mu.Unlock()

	me, err := p.client.GetMe(ctx)
	if err != nil {
		return fmt.Errorf("webex: getMe: %w", err)
	}
	p.mu.Lock()
	p.selfID = me.ID
	if len(me.Emails) > 0 {
		p.selfEmail = me.Emails[0]
	}
	p.mu.Unlock()
	slog.Info("webex: authenticated", "bot", me.DisplayName)

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Construct a fresh Platform via New(opts) instead of calling Start on a stopped instance
  2. Serialize lifecycle calls: ensure Stop completes before any new Start, and never call Start concurrently with Stop
  3. Restructure reconnect/restart logic to operate inside the platform's own reconnect loop rather than re-calling Start
  4. Check application shutdown sequencing so Start isn't invoked after the daemon initiated teardown

Example fix

// before
p.Stop()
p.Start(handler) // panics with "platform stopped"
// after
p.Stop()
p2, err := webex.New(opts)
if err != nil { return err }
p2.Start(handler)
Defensive patterns

Strategy: try-catch

Validate before calling

// do not call Start on a platform whose Stop has been invoked; track lifecycle state
if platformStopped { return errors.New("platform already stopped; construct a new one") }

Try / catch

if err := p.Start(handler); err != nil {
    if strings.Contains(err.Error(), "platform stopped") {
        return fmt.Errorf("create a new platform instance instead of restarting")
    }
    return err
}

Prevention

When it happens

Trigger: Calling Start after Stop (or during shutdown) on the same Platform instance; concurrent Start racing with a Stop that already set p.stopping=true.

Common situations: Restart logic that reuses a stopped Platform object instead of constructing a new one via New; daemon reload handlers calling Start during teardown.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/a2007f8b607deebe. Report an issue: GitHub.