{"record":{"id":"0c305a823901da4e","repo":"chenhg5/cc-connect","slug":"unknown-handler-type-q-must-be-command-or-http","errorCode":null,"errorMessage":"unknown handler type %q (must be command or http)","messagePattern":"unknown handler type %q \\(must be command or http\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/hooks.go","lineNumber":124,"sourceCode":"\nfunc validateHookConfig(h HookConfig) error {\n\tif h.Event == \"\" {\n\t\treturn fmt.Errorf(\"event is required\")\n\t}\n\tswitch HookHandlerType(h.Type) {\n\tcase HookHandlerCommand:\n\t\tif h.Command == \"\" {\n\t\t\treturn fmt.Errorf(\"command is required for type=command\")\n\t\t}\n\tcase HookHandlerHTTP:\n\t\tif h.URL == \"\" {\n\t\t\treturn fmt.Errorf(\"url is required for type=http\")\n\t\t}\n\t\tif !strings.HasPrefix(h.URL, \"http://\") && !strings.HasPrefix(h.URL, \"https://\") {\n\t\t\treturn fmt.Errorf(\"url must start with http:// or https://\")\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown handler type %q (must be command or http)\", h.Type)\n\t}\n\treturn nil\n}\n\n// Emit dispatches an event to all matching hooks.\nfunc (hm *HookManager) Emit(event HookEvent) {\n\tif hm == nil {\n\t\treturn\n\t}\n\tevent.Project = hm.project\n\tif event.Timestamp.IsZero() {\n\t\tevent.Timestamp = time.Now()\n\t}\n\n\thm.mu.RLock()\n\thooks := hm.hooks\n\thm.mu.RUnlock()\n","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/hooks.go#L106-L142","documentation":"validateHookConfig only accepts handler types \"command\" and \"http\". Any other Type value falls into the default branch and is rejected with this error naming the offending value. This catches typos and unsupported handler kinds early at HookManager construction.","triggerScenarios":"NewHookManager receives a hook whose Type is any string other than \"command\" or \"http\" — e.g. type = \"webhook\", type = \"script\", type = \"\" (empty), or a misspelling like \"comand\".","commonSituations":"Guessing handler type names not in the supported set; typo in config.toml; copying hook config from another tool with different type vocabulary; leaving the type key empty.","solutions":["Set type = \"command\" for a shell-command hook or type = \"http\" for a webhook hook","Fix the typo in the type value (check spelling against the two supported values)","Remove the type key only if a default is documented and intended (empty type still fails)","Consult the hooks documentation for the exact supported handler types"],"exampleFix":"// before (config.toml)\n[[hooks]]\nevent = \"before_agent\"\ntype = \"webhook\"\nurl = \"https://example.com/hook\"\n// after\n[[hooks]]\nevent = \"before_agent\"\ntype = \"http\"\nurl = \"https://example.com/hook\"","handlingStrategy":"validation","validationCode":"var validTypes = map[string]bool{\"command\": true, \"http\": true}\nfor i, h := range hooks {\n    if !validTypes[h.Type] {\n        return fmt.Errorf(\"hooks[%d]: unknown type %q (must be command or http)\", i, h.Type)\n    }\n}","typeGuard":null,"tryCatchPattern":"mgr, err := NewHookManager(hooks)\nif err != nil {\n    slog.Error(\"invalid hook config\", \"err\", err)\n    return fmt.Errorf(\"hook config: %w\", err)\n}","preventionTips":["Use only \"command\" or \"http\" as the hook type value","Keep the supported-types list in project docs next to config examples","Validate hook configs in CI to catch typos before deployment","Copy hook examples from config.example.toml rather than writing types from memory"],"tags":["hooks","validation","enum"],"backgroundTag":"invalid-enum-value","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}