{"record":{"id":"04a28cb1a59298d7","repo":"chenhg5/cc-connect","slug":"discord-timed-out-waiting-for-ready-event","errorCode":null,"errorMessage":"discord: timed out waiting for Ready event","messagePattern":"discord: timed out waiting for Ready event","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/discord/discord.go","lineNumber":471,"sourceCode":"\tthread, err := ops.StartStandaloneThread(parentChannelID, freshThreadName(title), threadType, 1440)\n\tif err != nil {\n\t\treturn \"\", replyContext{}, fmt.Errorf(\"start thread in channel %s: %w\", parentChannelID, err)\n\t}\n\tif err := ops.JoinThread(thread.ID); err != nil {\n\t\tslog.Debug(\"discord: join fresh thread failed\", \"thread\", thread.ID, \"error\", err)\n\t}\n\n\trc := replyContext{channelID: thread.ID, threadID: thread.ID}\n\treturn buildThreadSessionKey(thread.ID), rc, nil\n}\n\n// RegisterCommands registers bot commands with Discord for the slash command menu.\nfunc (p *Platform) RegisterCommands(commands []core.BotCommandInfo) error {\n\t// Wait for Ready event to ensure appID is populated\n\tselect {\n\tcase <-p.readyCh:\n\tcase <-time.After(15 * time.Second):\n\t\treturn fmt.Errorf(\"discord: timed out waiting for Ready event\")\n\t}\n\n\tvar cmds []*discordgo.ApplicationCommand\n\tfor _, c := range commands {\n\t\tif len(c.Command) > 32 {\n\t\t\tslog.Warn(\"discord: command name > 32 skip \" + c.Command)\n\t\t\tcontinue\n\t\t}\n\t\tdesc := c.Description\n\t\tif runes := []rune(desc); len(runes) > 100 {\n\t\t\tdesc = string(runes[:97]) + \"...\"\n\t\t}\n\t\tcmds = append(cmds, &discordgo.ApplicationCommand{\n\t\t\tName:        c.Command,\n\t\t\tDescription: desc,\n\t\t\t// A trick to be able to input any args\n\t\t\tOptions: []*discordgo.ApplicationCommandOption{\n\t\t\t\t{","sourceCodeStart":453,"sourceCodeEnd":489,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/discord/discord.go#L453-L489","documentation":"RegisterCommands needs the discordgo application ID, which is only populated after the gateway delivers the Ready event. The method blocks on p.readyCh with a 15-second timeout; if Ready has not arrived in that window it returns this error instead of registering with a zero app ID. It typically means the gateway never finished connecting.","triggerScenarios":"Calling RegisterCommands before/while Start() is still opening the gateway, an invalid bot token causing the Ready event to never fire, network/firewall blocking the Discord gateway, or registration attempted after Stop() cancelled the connection.","commonSituations":"Invalid DISCORD token in config, corporate proxies or firewalls blocking wss://gateway.discord.gg, slow networks exceeding 15s, registering commands immediately at process start before the connection is up, Discord gateway outages.","solutions":["Verify the bot token is valid — an auth failure prevents Ready entirely.","Ensure Start() is called and given time to connect before RegisterCommands; increase the readiness window if the network is slow.","Check network access to the Discord gateway (wss) and any proxy configuration.","Retry RegisterCommands with backoff after the timeout, or restructure to register commands from the on-Ready callback.","Call cc-connect doctor / check logs for gateway errors (EOF, auth) preceding this timeout."],"exampleFix":"// before\nerr := platform.RegisterCommands(cmds) // called before gateway ready\n// after\nif err := platform.Start(handler); err != nil {\n    log.Fatal(err)\n}\n// give the gateway a moment, then register with retry\nfor i := 0; i < 3; i++ {\n    if err := platform.RegisterCommands(cmds); err == nil {\n        break\n    } else if !strings.Contains(err.Error(), \"timed out waiting for Ready\") {\n        log.Fatal(err)\n    }\n    time.Sleep(5 * time.Second)\n}","handlingStrategy":"retry","validationCode":"// before registering, confirm the gateway is up:\nselect {\ncase <-p.readyCh:\ncase <-time.After(20 * time.Second):\n    return fmt.Errorf(\"gateway not ready; check token/network before RegisterCommands\")\n}","typeGuard":null,"tryCatchPattern":"if err := p.RegisterCommands(cmds); err != nil {\n    if strings.Contains(err.Error(), \"timed out waiting for Ready\") {\n        time.Sleep(5 * time.Second)\n        return p.RegisterCommands(cmds) // bounded retry\n    }\n    return err\n}","preventionTips":["Validate the bot token before startup (call the GetCurrentUser REST endpoint).","Always call Start() and wait for readiness before RegisterCommands.","Verify outbound wss access to gateway.discord.gg from the host.","Register commands from the on-Ready handler instead of a fixed wait."],"tags":["discord","gateway","timeout","readiness"],"backgroundTag":"request-timeout","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"}