chenhg5/cc-connect · error

discord: session not initialized

Error message

discord: session not initialized

What it means

sessionThreadOps.ResolveChannel resolves a Discord channel by ID, first from the local state cache then via the REST API. If the wrapped *discordgo.Session is nil, there is no client to query, so the method returns this error rather than panicking with a nil-pointer dereference.

Source

Thrown at platform/discord/discord.go:245

func (rc replyContext) useThreadChannel() bool {
	return rc.threadID != "" && rc.threadID == rc.channelID
}

type discordThreadOps interface {
	ResolveChannel(channelID string) (*discordgo.Channel, error)
	StartThread(channelID, messageID, name string, archiveDuration int) (*discordgo.Channel, error)
	StartStandaloneThread(channelID, name string, typ discordgo.ChannelType, archiveDuration int) (*discordgo.Channel, error)
	JoinThread(threadID string) error
}

type sessionThreadOps struct {
	session *discordgo.Session
}

func (o sessionThreadOps) ResolveChannel(channelID string) (*discordgo.Channel, error) {
	if o.session == nil {
		return nil, fmt.Errorf("discord: session not initialized")
	}
	if ch, err := o.session.State.Channel(channelID); err == nil && ch != nil {
		return ch, nil
	}
	return o.session.Channel(channelID)
}

func (o sessionThreadOps) StartThread(channelID, messageID, name string, archiveDuration int) (*discordgo.Channel, error) {
	if o.session == nil {
		return nil, fmt.Errorf("discord: session not initialized")
	}
	return o.session.MessageThreadStart(channelID, messageID, name, archiveDuration)
}

func (o sessionThreadOps) StartStandaloneThread(channelID, name string, typ discordgo.ChannelType, archiveDuration int) (*discordgo.Channel, error) {
	if o.session == nil {
		return nil, fmt.Errorf("discord: session not initialized")
	}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Ensure the bot startup completed successfully (check startup logs for connection errors before this appears).
  2. Verify the discordgo.Session is created and assigned to the threadOps before any handler or timer can invoke thread operations.
  3. Re-run with a valid bot token and network so Open() succeeds and the session is populated.
  4. If triggering operations on a timer, gate them on a 'connected' signal from the platform.

Example fix

// before
ops := sessionThreadOps{} // session never assigned
ch, err := ops.ResolveChannel(channelID)
// after
if p.session == nil {
    return fmt.Errorf("discord: bot not connected yet")
}
ops := sessionThreadOps{session: p.session}
ch, err := ops.ResolveChannel(channelID)
Defensive patterns

Strategy: type-guard

Validate before calling

func (o sessionThreadOps) Ready() bool { return o.session != nil }

Type guard

func threadOpsReady(o sessionThreadOps) bool {
    return o.session != nil
}

Try / catch

ch, err := ops.ResolveChannel(channelID)
if err != nil {
    if strings.Contains(err.Error(), "session not initialized") {
        // defer until bot connected; queue or retry
    }
}

Prevention

When it happens

Trigger: Calling ResolveChannel on a sessionThreadOps whose session field was never set — i.e. thread operations were constructed before discordgo.Session creation (typically before/without a successful Open of the gateway connection) or after the session was never assigned due to an earlier startup failure.

Common situations: Calling thread-related functionality before the bot finished connecting (handlers invoked prior to session assignment); startup failed (bad token, network) leaving the nil session in place while timers/commands still fire; race where a message handler runs concurrently with session initialization.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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