{"record":{"id":"21840b8c4cc4b589","repo":"sipeed/picoclaw","slug":"channel-manager-not-initialized","errorCode":null,"errorMessage":"channel manager not initialized","messagePattern":"channel manager not initialized","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/agent/agent_command.go","lineNumber":269,"sourceCode":"\t\t\t})\n\t\t\treturn toolInfos, nil\n\t\t},\n\t\tGetEnabledChannels: func() []string {\n\t\t\tif al.channelManager == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn al.channelManager.GetEnabledChannels()\n\t\t},\n\t\tGetActiveTurn: func() any {\n\t\t\tinfo := al.GetActiveTurn()\n\t\t\tif info == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn info\n\t\t},\n\t\tSwitchChannel: func(value string) error {\n\t\t\tif al.channelManager == nil {\n\t\t\t\treturn fmt.Errorf(\"channel manager not initialized\")\n\t\t\t}\n\t\t\tif _, exists := al.channelManager.GetChannel(value); !exists && value != \"cli\" {\n\t\t\t\treturn fmt.Errorf(\"channel '%s' not found or not enabled\", value)\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t}\n\trt.StopActiveTurn = func() (commands.StopResult, error) {\n\t\tif opts == nil {\n\t\t\treturn commands.StopResult{}, fmt.Errorf(\"process options not available\")\n\t\t}\n\t\treturn al.stopActiveTurnForSession(opts.Dispatch.SessionKey)\n\t}\n\tif agent != nil && agent.ContextBuilder != nil {\n\t\trt.ListSkillNames = agent.ContextBuilder.ListSkillNames\n\t}\n\trt.ReloadConfig = func() error {\n\t\tif al.reloadFunc == nil {","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/agent/agent_command.go#L251-L287","documentation":"The SwitchChannel runtime hook found al.channelManager == nil: the agent loop was built without a channel manager, so channel switching is impossible. This mirrors the cfg==nil guard style used elsewhere — a wiring/initialization defect rather than a user input problem.","triggerScenarios":"Calling /channel <name> in an embedded/test AgentLoop constructed without channel wiring; a headless integration that skipped channel setup; startup race where the command arrives before channel manager injection.","commonSituations":"Custom embeddings of pkg/agent that pass minimal options; unit tests exercising the command table directly; a code path that intentionally disables channels but still exposes the command.","solutions":["If you embed the runtime, construct/inject the channel manager before exposing SwitchChannel","Hide or disable the /channel command when no channels are wired","File a bug if this occurs in the stock CLI — the command should not be reachable in that state"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"if al.channelManager == nil { /* hide /channel command or warn at startup */ }","typeGuard":"func channelsReady(al *AgentLoop) bool { return al.channelManager != nil }","tryCatchPattern":"err := rt.SwitchChannel(name)\nif err != nil && strings.Contains(err.Error(), \"channel manager not initialized\") {\n    // wiring bug: do not retry; report and disable the channel command\n}","preventionTips":["Register the channel manager before exposing channel commands","Conditionally register SwitchChannel only when wiring exists","Add startup assertions for required collaborators"],"tags":["runtime","initialization","channels"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}