{"record":{"id":"c061380dc34ac81e","repo":"chenhg5/cc-connect","slug":"command-q-not-found","errorCode":null,"errorMessage":"command %q not found","messagePattern":"command %q not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/config.go","lineNumber":1729,"sourceCode":"\tdata, err := os.ReadFile(ConfigPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"read config: %w\", err)\n\t}\n\tcfg := &Config{}\n\tif err := toml.Unmarshal(data, cfg); err != nil {\n\t\treturn fmt.Errorf(\"parse config: %w\", err)\n\t}\n\tfound := false\n\tvar remaining []CommandConfig\n\tfor _, c := range cfg.Commands {\n\t\tif c.Name == name {\n\t\t\tfound = true\n\t\t} else {\n\t\t\tremaining = append(remaining, c)\n\t\t}\n\t}\n\tif !found {\n\t\treturn fmt.Errorf(\"command %q not found\", name)\n\t}\n\tcfg.Commands = remaining\n\treturn saveConfig(cfg)\n}\n\n// AddAlias adds a global alias and persists to config.\nfunc AddAlias(alias AliasConfig) error {\n\tconfigMu.Lock()\n\tdefer configMu.Unlock()\n\tif ConfigPath == \"\" {\n\t\treturn fmt.Errorf(\"config path not set\")\n\t}\n\tdata, err := os.ReadFile(ConfigPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"read config: %w\", err)\n\t}\n\tcfg := &Config{}\n\tif err := toml.Unmarshal(data, cfg); err != nil {","sourceCodeStart":1711,"sourceCodeEnd":1747,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/config/config.go#L1711-L1747","documentation":"RemoveCommand returns this error when no command with the given name exists in the parsed config's Commands list. The config loaded and parsed fine; the requested name simply is not registered. This is a lookup miss, not an I/O or parse failure.","triggerScenarios":"Calling config.RemoveCommand(name) where name matches no entry in cfg.Commands during the loop over cfg.Commands (config/config.go:1729), leaving found == false.","commonSituations":"Typo in the command name; case-sensitivity mismatch ('Deploy' vs 'deploy'); removing a command that was already removed (double-run of cleanup scripts); name defined per-project instead of globally, so the global list lookup misses it.","solutions":["List existing global commands (or read config.toml) and confirm the exact name before removing.","Match names exactly, normalizing case/whitespace if your tool trims inputs.","Treat 'not found' as success in idempotent cleanup scripts.","If the command lives in a project section, use the project-scoped removal API instead of the global one."],"exampleFix":"// before\nconfig.RemoveCommand(strings.TrimSpace(userInput)) // typos slip through\n\n// after\nnames, _ := config.ListCommands()\nif !slices.Contains(names, name) {\n    return nil // idempotent\n}\nif err := config.RemoveCommand(name); err != nil { return err }","handlingStrategy":"fallback","validationCode":"cmds, _ := config.ListCommands()\nfound := slices.ContainsFunc(cmds, func(c config.CommandConfig) bool { return c.Name == name })\nif !found {\n    return nil // already gone; idempotent success\n}","typeGuard":null,"tryCatchPattern":"err := config.RemoveCommand(name)\nif err != nil && strings.Contains(err.Error(), \"not found\") {\n    return nil // idempotent: command already absent\n}\nif err != nil {\n    return err\n}","preventionTips":["Match names exactly; trim and normalize user input before removal.","List commands and confirm the target before scripted removals.","Treat double-removal as success in idempotent cleanup scripts.","Check whether the command is project-scoped, which the global list will not contain."],"tags":["config","not-found","go"],"backgroundTag":"record-not-found","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"}