chenhg5/cc-connect · error

config: %s.platforms[%d].type is required

Error message

config: %s.platforms[%d].type is required

What it means

Each [[projects.platforms]] entry must specify a type identifying which messaging platform adapter to instantiate (e.g. "feishu", "telegram"). The validator loops over the project's platforms and rejects any entry whose Type field is empty, since the registry lookup would otherwise fail with a less helpful error.

Source

Thrown at config/config.go:1039

		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 {
			return fmt.Errorf("config: %s.agent_session_idle_timeout_mins must be >= 0", prefix)
		}
		if err := validateRunAsUser(prefix, proj.RunAsUser); err != nil {
			return err

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Add type = "<platform>" to the failing platform block (indexes shown in the message, e.g. platforms[0])
  2. Use a compiled-in platform name — check config.example.toml or the plugin_*.go build tags
  3. Ensure each [[projects.platforms]] header starts a fresh block containing its own type key

Example fix

// before
[[projects.platforms]]
token = "x"
// after
[[projects.platforms]]
type = "telegram"
token = "x"
Defensive patterns

Strategy: validation

Validate before calling

for i, p := range cfg.Projects {
    for j, pl := range p.Platforms {
        if pl.Type == "" {
            return fmt.Errorf("projects[%d].platforms[%d].type is required", i, j)
        }
    }
}

Prevention

When it happens

Trigger: A [[projects.platforms]] table exists under a project but its type key is missing or set to an empty string, e.g. [[projects.platforms]] with only options like token/chat_id but no type = "...".

Common situations: Copying a platform block and deleting the type line; adding a second platform entry via array syntax and forgetting the type; mis-indented TOML placing type under the wrong table.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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