{"record":{"id":"36d8c0dd8cb61ed1","repo":"chenhg5/cc-connect","slug":"discord-session-not-initialized","errorCode":null,"errorMessage":"discord: session not initialized","messagePattern":"discord: session not initialized","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/discord/discord.go","lineNumber":245,"sourceCode":"\nfunc (rc replyContext) useThreadChannel() bool {\n\treturn rc.threadID != \"\" && rc.threadID == rc.channelID\n}\n\ntype discordThreadOps interface {\n\tResolveChannel(channelID string) (*discordgo.Channel, error)\n\tStartThread(channelID, messageID, name string, archiveDuration int) (*discordgo.Channel, error)\n\tStartStandaloneThread(channelID, name string, typ discordgo.ChannelType, archiveDuration int) (*discordgo.Channel, error)\n\tJoinThread(threadID string) error\n}\n\ntype sessionThreadOps struct {\n\tsession *discordgo.Session\n}\n\nfunc (o sessionThreadOps) ResolveChannel(channelID string) (*discordgo.Channel, error) {\n\tif o.session == nil {\n\t\treturn nil, fmt.Errorf(\"discord: session not initialized\")\n\t}\n\tif ch, err := o.session.State.Channel(channelID); err == nil && ch != nil {\n\t\treturn ch, nil\n\t}\n\treturn o.session.Channel(channelID)\n}\n\nfunc (o sessionThreadOps) StartThread(channelID, messageID, name string, archiveDuration int) (*discordgo.Channel, error) {\n\tif o.session == nil {\n\t\treturn nil, fmt.Errorf(\"discord: session not initialized\")\n\t}\n\treturn o.session.MessageThreadStart(channelID, messageID, name, archiveDuration)\n}\n\nfunc (o sessionThreadOps) StartStandaloneThread(channelID, name string, typ discordgo.ChannelType, archiveDuration int) (*discordgo.Channel, error) {\n\tif o.session == nil {\n\t\treturn nil, fmt.Errorf(\"discord: session not initialized\")\n\t}","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/discord/discord.go#L227-L263","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the bot startup completed successfully (check startup logs for connection errors before this appears).","Verify the discordgo.Session is created and assigned to the threadOps before any handler or timer can invoke thread operations.","Re-run with a valid bot token and network so Open() succeeds and the session is populated.","If triggering operations on a timer, gate them on a 'connected' signal from the platform."],"exampleFix":"// before\nops := sessionThreadOps{} // session never assigned\nch, err := ops.ResolveChannel(channelID)\n// after\nif p.session == nil {\n    return fmt.Errorf(\"discord: bot not connected yet\")\n}\nops := sessionThreadOps{session: p.session}\nch, err := ops.ResolveChannel(channelID)","handlingStrategy":"type-guard","validationCode":"func (o sessionThreadOps) Ready() bool { return o.session != nil }","typeGuard":"func threadOpsReady(o sessionThreadOps) bool {\n    return o.session != nil\n}","tryCatchPattern":"ch, err := ops.ResolveChannel(channelID)\nif err != nil {\n    if strings.Contains(err.Error(), \"session not initialized\") {\n        // defer until bot connected; queue or retry\n    }\n}","preventionTips":["Construct sessionThreadOps only after the discordgo session exists","Gate message/timer handlers on a connected flag set after Open() succeeds","Fail startup loudly if Open() errors so downstream nil-session use cannot happen","Avoid firing thread operations during the connecting phase"],"tags":["discord","nil-session","state","threads"],"backgroundTag":"missing-required-argument","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}