chenhg5/cc-connect · critical
config: at least one [[projects]] entry is required
Error message
config: at least one [[projects]] entry is required
What it means
The validator requires at least one [[projects]] entry in the config file. CC-Connect routes messages from platforms to coding agents per project, so an empty or missing projects list leaves the daemon with nothing to run and is rejected at load time in config/config.go.
Source
Thrown at config/config.go:1024
func (c *Config) validateInternal(permissive bool) error {
if err := validateDisplayConfig("display", &c.Display); err != nil {
return err
}
switch strings.ToLower(strings.TrimSpace(c.AttachmentSend)) {
case "", "on", "off":
default:
return fmt.Errorf("config: attachment_send must be \"on\" or \"off\"")
}
if c.Relay.TimeoutSecs != nil && *c.Relay.TimeoutSecs < 0 {
return fmt.Errorf("config: relay.timeout_secs must be >= 0")
}
switch strings.ToLower(strings.TrimSpace(c.Relay.Visibility)) {
case "", "full", "summary", "none":
default:
return fmt.Errorf("config: relay.visibility must be \"full\", \"summary\", or \"none\"")
}
if len(c.Projects) == 0 {
return fmt.Errorf("config: at least one [[projects]] entry is required")
}
for i, proj := range c.Projects {
prefix := fmt.Sprintf("projects[%d]", i)
if proj.Name == "" {
return fmt.Errorf("config: %s.name is required", prefix)
}
if proj.Agent.Type == "" {
return fmt.Errorf("config: %s.agent.type is required", prefix)
}
if len(proj.Platforms) == 0 && !permissive {
return fmt.Errorf("config: %s needs at least one [[projects.platforms]]", prefix)
}
for j, p := range proj.Platforms {
if p.Type == "" {
return fmt.Errorf("config: %s.platforms[%d].type is required", prefix, j)
}
}
if proj.Mode == "multi-workspace" {View on GitHub (pinned to 4000b2338a)
Solutions
- Add at least one [[projects]] block with a name, agent.type, and platforms to config.toml
- Un-comment the example [[projects]] section in your config
- Copy a working example from config.example.toml
Example fix
// before [relay] visibility = "summary" // after [relay] visibility = "summary" [[projects]] name = "my-app" agent.type = "claudecode" [[projects.platforms]] type = "feishu"
Defensive patterns
Strategy: validation
Validate before calling
if len(cfg.Projects) == 0 {
return fmt.Errorf("config.toml has no [[projects]] entries")
} Try / catch
if err := config.Load(path); err != nil {
slog.Error("config load failed", "err", err)
os.Exit(1)
} Prevention
- Start from config.example.toml and fill in a project block first
- Keep at least one [[projects]] block, even a disabled-looking minimal one
- Validate config in CI before shipping
When it happens
Trigger: Loading a config.toml that has no [[projects]] array at all, or where all [[projects]] blocks were commented out or deleted, so c.Projects has length 0.
Common situations: Fresh installs with a minimal config containing only [relay] and platform settings; users commenting out their only project while debugging; copying a platform-only snippet from docs.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- tmux: 'session' option is required (name of the tmux session
- config: relay.visibility must be "full", "summary", or "none
- config: %s.name is required
- config: %s.agent.type is required
- config: %s needs at least one [[projects.platforms]]
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/1f9b7cbd9c256d01.
Report an issue: GitHub.