{"record":{"id":"a5bda7de65dca657","repo":"chenhg5/cc-connect","slug":"config-s-agent-type-is-required","errorCode":null,"errorMessage":"config: %s.agent.type is required","messagePattern":"config: (.+?)\\.agent\\.type is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/config.go","lineNumber":1032,"sourceCode":"\t}\n\tif c.Relay.TimeoutSecs != nil && *c.Relay.TimeoutSecs < 0 {\n\t\treturn fmt.Errorf(\"config: relay.timeout_secs must be >= 0\")\n\t}\n\tswitch strings.ToLower(strings.TrimSpace(c.Relay.Visibility)) {\n\tcase \"\", \"full\", \"summary\", \"none\":\n\tdefault:\n\t\treturn fmt.Errorf(\"config: relay.visibility must be \\\"full\\\", \\\"summary\\\", or \\\"none\\\"\")\n\t}\n\tif len(c.Projects) == 0 {\n\t\treturn fmt.Errorf(\"config: at least one [[projects]] entry is required\")\n\t}\n\tfor i, proj := range c.Projects {\n\t\tprefix := fmt.Sprintf(\"projects[%d]\", i)\n\t\tif proj.Name == \"\" {\n\t\t\treturn fmt.Errorf(\"config: %s.name is required\", prefix)\n\t\t}\n\t\tif proj.Agent.Type == \"\" {\n\t\t\treturn fmt.Errorf(\"config: %s.agent.type is required\", prefix)\n\t\t}\n\t\tif len(proj.Platforms) == 0 && !permissive {\n\t\t\treturn fmt.Errorf(\"config: %s needs at least one [[projects.platforms]]\", prefix)\n\t\t}\n\t\tfor j, p := range proj.Platforms {\n\t\t\tif p.Type == \"\" {\n\t\t\t\treturn fmt.Errorf(\"config: %s.platforms[%d].type is required\", prefix, j)\n\t\t\t}\n\t\t}\n\t\tif proj.Mode == \"multi-workspace\" {\n\t\t\tif proj.BaseDir == \"\" {\n\t\t\t\treturn fmt.Errorf(\"project %q: multi-workspace mode requires base_dir\", proj.Name)\n\t\t\t}\n\t\t\tif _, ok := proj.Agent.Options[\"work_dir\"]; ok {\n\t\t\t\treturn fmt.Errorf(\"project %q: multi-workspace mode conflicts with agent work_dir (use base_dir instead)\", proj.Name)\n\t\t\t}\n\t\t}\n\t\tif proj.ResetOnIdleMins != nil && *proj.ResetOnIdleMins < 0 {","sourceCodeStart":1014,"sourceCodeEnd":1050,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/config/config.go#L1014-L1050","documentation":"Every project must declare which coding agent it uses via the agent.type field (e.g. \"claudecode\", \"codex\", \"gemini\"). The validator rejects a project whose Agent.Type is empty because the engine cannot construct an agent instance from an unknown/blank type name.","triggerScenarios":"A [[projects]] block with no [projects.agent] table, or with [projects.agent] present but type missing/empty, so proj.Agent.Type == \"\" during validation.","commonSituations":"Adding a new project and copying only the platforms section; mistyping the table header (e.g. [projects.agents] plural) so type lands nowhere; deleting the agent table while troubleshooting.","solutions":["Add agent.type = \"<agent>\" to the failing [[projects]] block (index in the message)","Use an agent name that is registered/compiled in (e.g. \"claudecode\", \"codex\", \"opencode\") — see config.example.toml","Ensure the table header is exactly [projects.agent], singular"],"exampleFix":"// before\n[[projects]]\nname = \"my-app\"\n[[projects.platforms]]\ntype = \"telegram\"\n// after\n[[projects]]\nname = \"my-app\"\nagent.type = \"claudecode\"\n[[projects.platforms]]\ntype = \"telegram\"","handlingStrategy":"validation","validationCode":"for i, p := range cfg.Projects {\n    if p.Agent.Type == \"\" {\n        return fmt.Errorf(\"projects[%d].agent.type is required\", i)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair agent.type with a project when copying templates","Verify the table header is [projects.agent] (singular)","Confirm the agent type is registered in your build (check plugin_agent_*.go tags)"],"tags":["config","validation","go"],"backgroundTag":"missing-required-config-field","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"}