{"record":{"id":"2cf0784774169c4a","repo":"chenhg5/cc-connect","slug":"discord-token-is-required","errorCode":null,"errorMessage":"discord: token is required","messagePattern":"discord: token is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"platform/discord/discord.go","lineNumber":83,"sourceCode":"\tself                       core.Platform\n\n\tmu               sync.RWMutex\n\tsession          *discordgo.Session\n\tcancel           context.CancelFunc\n\tstopping         bool\n\teverConnected    bool\n\tlifecycleHandler core.PlatformLifecycleHandler\n}\n\nconst (\n\tdiscordInitialReconnectBackoff = 5 * time.Second\n\tdiscordMaxReconnectBackoff     = 5 * time.Minute\n)\n\nfunc New(opts map[string]any) (core.Platform, error) {\n\ttoken, _ := opts[\"token\"].(string)\n\tif token == \"\" {\n\t\treturn nil, fmt.Errorf(\"discord: token is required\")\n\t}\n\tallowFrom, _ := opts[\"allow_from\"].(string)\n\tcore.CheckAllowFrom(\"discord\", allowFrom)\n\tguildID, _ := opts[\"guild_id\"].(string)\n\tvar groupReplyAllGuilds []string\n\tif guilds, _ := opts[\"group_reply_all_guilds\"].(string); guilds != \"\" {\n\t\tfor _, g := range strings.Split(guilds, \",\") {\n\t\t\tif g = strings.TrimSpace(g); g != \"\" {\n\t\t\t\tgroupReplyAllGuilds = append(groupReplyAllGuilds, g)\n\t\t\t}\n\t\t}\n\t} else if all, _ := opts[\"group_reply_all\"].(bool); all {\n\t\tgroupReplyAllGuilds = []string{\"*\"}\n\t}\n\tshareSessionInChannel, _ := opts[\"share_session_in_channel\"].(bool)\n\tthreadIsolation, _ := opts[\"thread_isolation\"].(bool)\n\trespondToAtEveryoneAndHere, _ := opts[\"respond_to_at_everyone_and_here\"].(bool)\n\t// Default to \"compact\" so streaming edits work out of the box (Discord","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/discord/discord.go#L65-L101","documentation":"The Discord platform constructor requires a bot token, read from the opts map under the key \"token\". If the option is absent or not a non-empty string, New returns this error instead of constructing a platform that could not authenticate. It is a fail-fast config validation at startup.","triggerScenarios":"Calling discord.New(opts) with opts missing the \"token\" key, with opts[\"token\"] set to \"\" , or with a non-string value (e.g. a number read via TOML), so the type assertion opts[\"token\"].(string) yields \"\".","commonSituations":"config.toml [platforms.discord] section missing the token field; token supplied via environment variable that is unset/empty; token value accidentally quoted as an integer or placed under the wrong platform name; typo like \"bot_token\" instead of \"token\".","solutions":["Add the bot token to config.toml: under the discord platform section set token = \"your-bot-token\".","If the token comes from an env var, verify it is exported and non-empty before starting cc-connect.","Ensure the value is a TOML string (wrap in quotes), not a number.","Confirm the option key is exactly \"token\" (not \"bot_token\" or \"discord_token\")."],"exampleFix":"// before\n[[platforms]]\nname = \"discord\"\n# token missing\n\n// after\n[[platforms]]\nname = \"discord\"\ntoken = \"MTAw...bot-token...\"","handlingStrategy":"validation","validationCode":"cfg := os.Getenv(\"DISCORD_BOT_TOKEN\")\nif cfg == \"\" {\n    log.Fatal(\"DISCORD_BOT_TOKEN is not set\")\n}","typeGuard":"func hasToken(opts map[string]any) bool {\n    t, ok := opts[\"token\"].(string)\n    return ok && t != \"\"\n}","tryCatchPattern":"p, err := discord.New(opts)\nif err != nil && strings.Contains(err.Error(), \"token is required\") {\n    log.Fatal(\"discord: missing token in config\")\n}","preventionTips":["Always set token as a quoted TOML string in the discord platform section","Load secrets from environment with a startup check for emptiness","Use exactly the key \"token\"; avoid alias key names","Run cc-connect config validation/doctor before starting the daemon"],"tags":["discord","configuration","authentication","startup"],"backgroundTag":"missing-api-key","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}