sipeed/picoclaw · error

error creating channel manager: %w

Error message

error creating channel manager: %w

What it means

channels.NewManager failed while constructing the channel manager, and the gateway aborted startup after stopping the media store cleanup goroutine. The error originates in m.initChannels(&cfg.Channels), which validates and instantiates each configured channel (unknown type, bad config, missing token).

Source

Thrown at pkg/gateway/gateway.go:464

		Enabled:  cfg.Tools.MediaCleanup.Enabled,
		MaxAge:   time.Duration(cfg.Tools.MediaCleanup.MaxAge) * time.Minute,
		Interval: time.Duration(cfg.Tools.MediaCleanup.Interval) * time.Minute,
	})
	if fms, ok := runningServices.MediaStore.(*media.FileMediaStore); ok {
		fms.Start()
	}

	runningServices.ChannelManager, err = channels.NewManager(
		cfg,
		msgBus,
		runningServices.MediaStore,
		channels.WithRuntimeEvents(agentLoop.RuntimeEventBus()),
	)
	if err != nil {
		if fms, ok := runningServices.MediaStore.(*media.FileMediaStore); ok {
			fms.Stop()
		}
		return nil, fmt.Errorf("error creating channel manager: %w", err)
	}

	agentLoop.SetChannelManager(runningServices.ChannelManager)
	agentLoop.SetMediaStore(runningServices.MediaStore)

	transcriber := asr.DetectTranscriber(cfg)
	if transcriber != nil {
		agentLoop.SetTranscriber(transcriber)
		logger.InfoCF("voice", "Transcription enabled (agent-level)", map[string]any{"provider": transcriber.Name()})
	}

	ttsAvailable := tts.DetectTTS(cfg) != nil

	enabledChannels := runningServices.ChannelManager.GetEnabledChannels()
	if len(enabledChannels) > 0 {
		fmt.Printf("✓ Channels enabled: %s\n", enabledChannels)
	} else {
		fmt.Println("⚠ Warning: No channels enabled")

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Check the wrapped error from initChannels — it names the failing channel
  2. Validate every entry under channels in config.json: correct type string and required fields/tokens
  3. Ensure channel credential env vars are set in the gateway process environment
  4. Run a config lint/dry-run if available before restart

Example fix

// before
"channels": { "telegramm": { "enabled": true, "token": "..." } }
// after
"channels": { "telegram": { "enabled": true, "token": "..." } }
Defensive patterns

Strategy: validation

Validate before calling

for name, ch := range cfg.Channels {
    if !knownChannelTypes[ch.Type] {
        return fmt.Errorf("unknown channel type %q for %s", ch.Type, name)
    }
}

Try / catch

cm, err := channels.NewManager(cfg, bus, store, opts...)
if err != nil {
    // manager constructor also stops media cleanup upstream; ensure fms.Stop() on your side
    return fmt.Errorf("error creating channel manager: %w", err)
}

Prevention

When it happens

Trigger: config.json declares a channel with an unsupported/misspelled type, a channel with missing required credentials, or duplicate channel names; NewManager returns the initChannels error and gateway.go wraps it as 'error creating channel manager' after stopping FileMediaStore.

Common situations: Upgrading the gateway to a version that renamed/removed a channel type; typos in the channels section; env vars for channel tokens unset at boot; malformed config.json after manual edit.

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/1b812f2d3efa2b72. Report an issue: GitHub.