{"record":{"id":"5b50205c47187ec4","repo":"sipeed/picoclaw","slug":"irc-nick-is-required","errorCode":null,"errorMessage":"irc nick is required","messagePattern":"irc nick is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/channels/irc/irc.go","lineNumber":34,"sourceCode":")\n\n// IRCChannel implements the Channel interface for IRC servers.\ntype IRCChannel struct {\n\t*channels.BaseChannel\n\tbc     *config.Channel\n\tconfig *config.IRCSettings\n\tconn   *ircevent.Connection\n\tctx    context.Context\n\tcancel context.CancelFunc\n}\n\n// NewIRCChannel creates a new IRC channel.\nfunc NewIRCChannel(bc *config.Channel, cfg *config.IRCSettings, messageBus *bus.MessageBus) (*IRCChannel, error) {\n\tif cfg.Server == \"\" {\n\t\treturn nil, fmt.Errorf(\"irc server is required\")\n\t}\n\tif cfg.Nick == \"\" {\n\t\treturn nil, fmt.Errorf(\"irc nick is required\")\n\t}\n\n\tbase := channels.NewBaseChannel(\"irc\", cfg, messageBus, bc.AllowFrom,\n\t\tchannels.WithMaxMessageLength(400),\n\t\tchannels.WithGroupTrigger(bc.GroupTrigger),\n\t\tchannels.WithReasoningChannelID(bc.ReasoningChannelID),\n\t)\n\n\treturn &IRCChannel{\n\t\tBaseChannel: base,\n\t\tbc:          bc,\n\t\tconfig:      cfg,\n\t}, nil\n}\n\n// Start connects to the IRC server and begins listening.\nfunc (c *IRCChannel) Start(ctx context.Context) error {\n\tlogger.InfoC(\"irc\", \"Starting IRC channel\")","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/channels/irc/irc.go#L16-L52","documentation":"Constructor validation error from NewIRCChannel: IRCSettings.Nick is empty, so the channel cannot be built. IRC requires a nickname for registration (NICK/USER handshake); without one, every connect attempt would be malformed. Fail-fast at construction instead.","triggerScenarios":"An irc channel entry is configured with a server but no nick — missing 'nick' key in JSON settings or unset PICOCLAW_CHANNELS_IRC_NICK env var.","commonSituations":"Copy-pasted config template with placeholders left empty; nick stored in a secret manager that failed to load into env; key spelled 'nickname' or 'username' instead of 'nick'.","solutions":["Set nick (json key 'nick' or env PICOCLAW_CHANNELS_IRC_NICK), e.g. \"mybot\".","Pick a unique nick to avoid 433 collisions; consider appending -[0-9] variants if the network is busy.","Verify the env var is actually exported into the service's environment.","Lint required IRC fields (server AND nick) in CI."],"exampleFix":"# before\n{ \"type\": \"irc\", \"settings\": { \"server\": \"irc.libera.chat:6697\" } }\n\n# after\n{ \"type\": \"irc\", \"settings\": { \"server\": \"irc.libera.chat:6697\", \"nick\": \"mybot\" } }","handlingStrategy":"validation","validationCode":"if cfg.Nick == \"\" {\n    return nil, fmt.Errorf(\"irc settings incomplete: 'nick' is required\")\n}\nif len(cfg.Nick) > 30 || strings.ContainsAny(cfg.Nick, \" #&!*?,@\") {\n    return nil, fmt.Errorf(\"nick %q is not a valid IRC nickname\", cfg.Nick)\n}","typeGuard":null,"tryCatchPattern":"if _, err := irc.NewIRCChannel(bc, cfg, messageBus); err != nil {\n    log.Fatalf(\"channel config invalid: %v\", err) // config error: fix before deploy\n}","preventionTips":["Lint required IRC fields (server AND nick) in CI","Choose a unique nick to avoid 433 collisions","Verify PICOCLAW_CHANNELS_IRC_NICK is set in the service environment"],"tags":["irc","config","go","validation","startup"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}