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

  1. Add at least one [[projects]] block with a name, agent.type, and platforms to config.toml
  2. Un-comment the example [[projects]] section in your config
  3. 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

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


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/1f9b7cbd9c256d01. Report an issue: GitHub.