{"record":{"id":"161afd3ac4d7956d","repo":"sipeed/picoclaw","slug":"channel-s-not-found","errorCode":null,"errorMessage":"channel %s not found","messagePattern":"channel (.+?) not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/agent/agent_init.go","lineNumber":229,"sourceCode":"\t\t\t\t}\n\t\t\t\tif al.channelManager != nil && channel != \"\" {\n\t\t\t\t\treturn al.channelManager.SendMessage(ctx, outboundMessage)\n\t\t\t\t}\n\t\t\t\tpubCtx, pubCancel := context.WithTimeout(context.Background(), 5*time.Second)\n\t\t\t\tdefer pubCancel()\n\t\t\t\treturn msgBus.PublishOutbound(pubCtx, outboundMessage)\n\t\t\t})\n\t\t\tagent.Tools.Register(messageTool)\n\t\t}\n\t\tif cfg.Tools.IsToolEnabled(\"reaction\") {\n\t\t\treactionTool := tools.NewReactionTool()\n\t\t\treactionTool.SetReactionCallback(func(ctx context.Context, channel, chatID, messageID string) error {\n\t\t\t\tif al.channelManager == nil {\n\t\t\t\t\treturn fmt.Errorf(\"channel manager not configured\")\n\t\t\t\t}\n\t\t\t\tch, ok := al.channelManager.GetChannel(channel)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn fmt.Errorf(\"channel %s not found\", channel)\n\t\t\t\t}\n\t\t\t\trc, ok := ch.(channels.ReactionCapable)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn fmt.Errorf(\"channel %s does not support reactions\", channel)\n\t\t\t\t}\n\t\t\t\t_, err := rc.ReactToMessage(ctx, chatID, messageID)\n\t\t\t\treturn err\n\t\t\t})\n\t\t\tagent.Tools.Register(reactionTool)\n\t\t}\n\n\t\t// Send file tool (outbound media via MediaStore — store injected later by SetMediaStore)\n\t\tif cfg.Tools.IsToolEnabled(\"send_file\") {\n\t\t\tsendFileTool := tools.NewSendFileTool(\n\t\t\t\tagent.Workspace,\n\t\t\t\tcfg.Agents.Defaults.RestrictToWorkspace,\n\t\t\t\tcfg.Agents.Defaults.GetMaxMediaSize(),\n\t\t\t\tnil,","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/agent/agent_init.go#L211-L247","documentation":"The reaction tool found the channel manager but channels.Manager.GetChannel(name) returned false for the name the model passed. GetChannel (pkg/channels/manager.go:1871) is a case-sensitive map lookup over channels registered via RegisterChannel, so the argument must exactly match a registered channel name. The channel argument comes straight from the LLM, so hallucinated, stale, or misspelled names fail here.","triggerScenarios":"The agent calls the reaction tool with channel=\"Telegram\" while the registered name is \"telegram\"; the channel was renamed/removed in config without a restart; the channel failed init and was never registered into the manager's map.","commonSituations":"Case mismatch between tool argument and registered name; renaming a channel in config while agent prompts or session history still reference the old name; channel disabled (enabled=false) in config; model typos.","solutions":["List registered names via cm.GetStatus() and correct the tool argument or the config so they match exactly (case-sensitive)","Enable the channel in config (channels.<name>.enabled=true with valid credentials) and restart picoclaw","If the channel was renamed, restart so RegisterChannel sees the new key, and update prompts that hard-code channel names","Give the model the valid channel list in its system prompt so it stops guessing"],"exampleFix":"// config/config.json — before\n\"channels\": { \"telegram\": { \"enabled\": false } }\n\n// after\n\"channels\": { \"telegram\": { \"enabled\": true, \"token\": \"...\" } }","handlingStrategy":"validation","validationCode":"for name := range cm.GetStatus() {\n    log.Printf(\"registered channel: %s\", name)\n}\nch, ok := cm.GetChannel(channelName)\nif !ok {\n    return fmt.Errorf(\"channel %q not registered; fix config or tool argument\", channelName)\n}\n_ = ch // safe to proceed with the reaction","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register channels under stable lowercase names and never reuse old names for renamed channels","Put the exact registered channel names in the agent's system prompt so the model passes valid values","Restart picoclaw after changing channels config so RegisterChannel state matches config"],"tags":["go","picoclaw","channels","reaction-tool","config","llm-tool-args"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}