chenhg5/cc-connect · error

config: %s needs at least one [[projects.platforms]]

Error message

config: %s needs at least one [[projects.platforms]]

What it means

A project must be attached to at least one messaging platform via [[projects.platforms]]. The validator skips this check only in permissive mode (permissive == true, used for partial validation); otherwise a project with zero platforms is rejected since messages would have nowhere to arrive or be replied to.

Source

Thrown at config/config.go:1035

	}
	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" {
			if proj.BaseDir == "" {
				return fmt.Errorf("project %q: multi-workspace mode requires base_dir", proj.Name)
			}
			if _, ok := proj.Agent.Options["work_dir"]; ok {
				return fmt.Errorf("project %q: multi-workspace mode conflicts with agent work_dir (use base_dir instead)", proj.Name)
			}
		}
		if proj.ResetOnIdleMins != nil && *proj.ResetOnIdleMins < 0 {
			return fmt.Errorf("config: %s.reset_on_idle_mins must be >= 0", prefix)
		}
		if proj.AgentSessionIdleTimeoutMins != nil && *proj.AgentSessionIdleTimeoutMins < 0 {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Add at least one [[projects.platforms]] block with a type under the failing project
  2. Restore a commented-out [[projects.platforms]] entry
  3. If this is a dry-run/partial load, use the permissive validation path if available

Example fix

// before
[[projects]]
name = "my-app"
agent.type = "claudecode"
// after
[[projects]]
name = "my-app"
agent.type = "claudecode"
[[projects.platforms]]
type = "feishu"
Defensive patterns

Strategy: validation

Validate before calling

for i, p := range cfg.Projects {
    if len(p.Platforms) == 0 {
        return fmt.Errorf("projects[%d] has no platforms", i)
    }
}

Prevention

When it happens

Trigger: Loading a full (non-permissive) config where a [[projects]] block has no [[projects.platforms]] sub-tables, or they were all commented out, making len(proj.Platforms) == 0.

Common situations: Creating a project intended for later use but leaving it unattached; commenting out a platform while debugging credentials and forgetting to restore it; template configs with the platforms section omitted.

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/e631fb95fc6286ef. Report an issue: GitHub.