{"record":{"id":"d916a437c6be698b","repo":"sipeed/picoclaw","slug":"irc-server-is-required","errorCode":null,"errorMessage":"irc server is required","messagePattern":"irc server is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/channels/irc/irc.go","lineNumber":31,"sourceCode":"\t\"github.com/sipeed/picoclaw/pkg/channels\"\n\t\"github.com/sipeed/picoclaw/pkg/config\"\n\t\"github.com/sipeed/picoclaw/pkg/logger\"\n)\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","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/channels/irc/irc.go#L13-L49","documentation":"Constructor validation error from NewIRCChannel: IRCSettings.Server is empty, so the channel cannot be built. This is a fail-fast config check — the IRC connection has no host to dial. The channel registration for this instance aborts at startup.","triggerScenarios":"A channel entry of type 'irc' is configured without a server value — missing key in config JSON, unset PICOCLAW_CHANNELS_IRC_SERVER env var, or a typo'd key that silently defaults to empty.","commonSituations":"New deployment with incomplete config; migrating config where the IRC block was dropped; env var renamed or not exported into the service environment; YAML/JSON key mismatch (config reads json/env, not yaml, for server).","solutions":["Set the IRC server including port, e.g. server: \"irc.libera.chat:6697\" (json key 'server' or env PICOCLAW_CHANNELS_IRC_SERVER).","Confirm the settings block is attached to the right channel entry and the key is spelled 'server'.","If using env vars, verify they are exported to the process (printenv in the service context).","Add a config lint step that rejects empty required fields before deploy."],"exampleFix":"# before\n{ \"type\": \"irc\", \"settings\": {} }\n\n# after\n{ \"type\": \"irc\", \"settings\": { \"server\": \"irc.libera.chat:6697\", \"nick\": \"mybot\" } }","handlingStrategy":"validation","validationCode":"if cfg.Server == \"\" {\n    return nil, fmt.Errorf(\"irc settings incomplete: 'server' is required (e.g. irc.libera.chat:6697)\")\n}","typeGuard":null,"tryCatchPattern":"if _, err := irc.NewIRCChannel(bc, cfg, messageBus); err != nil {\n    // fail startup loudly: this error means config, not runtime, is wrong\n    log.Fatalf(\"channel config invalid: %v\", err)\n}","preventionTips":["Add a config lint step rejecting empty required IRC fields","Verify env vars (PICOCLAW_CHANNELS_IRC_SERVER) are exported to the service","Include host:port in server, matching the TLS setting"],"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"}