chenhg5/cc-connect · error
dingtalk: robot_code is required (or client_id)
Error message
dingtalk: robot_code is required (or client_id)
What it means
After falling back robotCode to client_id, New validates that a robot code was resolved. This error means neither 'robot_code' nor a usable 'client_id' was available, so the platform cannot identify the robot in API calls (e.g. messageFiles/download requires robotCode). In practice it is reached when client_id was empty but client_secret was set, or robot_code was set to a non-string/empty value.
Source
Thrown at platform/dingtalk/dingtalk.go:112
degradeMu sync.Mutex
}
func New(opts map[string]any) (core.Platform, error) {
clientID, _ := opts["client_id"].(string)
clientSecret, _ := opts["client_secret"].(string)
robotCode, _ := opts["robot_code"].(string)
allowFrom, _ := opts["allow_from"].(string)
core.CheckAllowFrom("dingtalk", allowFrom)
shareSessionInChannel, _ := opts["share_session_in_channel"].(bool)
if clientID == "" || clientSecret == "" {
return nil, fmt.Errorf("dingtalk: client_id and client_secret are required")
}
if robotCode == "" {
robotCode = clientID // fallback to client_id if robot_code not specified
}
// Validate robot_code format (should not be empty after fallback)
if robotCode == "" {
return nil, fmt.Errorf("dingtalk: robot_code is required (or client_id)")
}
reactionEmoji, _ := opts["reaction_emoji"].(string)
reactionEmoji = strings.TrimSpace(reactionEmoji)
if reactionEmoji == "" {
reactionEmoji = defaultReactionEmoji
}
if strings.EqualFold(reactionEmoji, "none") {
reactionEmoji = ""
}
doneEmoji, _ := opts["done_emoji"].(string)
doneEmoji = strings.TrimSpace(doneEmoji)
if strings.EqualFold(doneEmoji, "none") {
doneEmoji = ""
}
// agent_id is required for work notifications API (numeric type)
// Try to read as int64 first, then float64 (JSON numbers), fallback to 0View on GitHub (pinned to 4000b2338a)
Solutions
- Provide 'client_id' (AppKey) — robotCode will automatically fall back to it.
- Or explicitly set 'robot_code' to your robot's code if it differs from the client_id.
- Validate that both values are non-empty strings before calling New.
Example fix
// before
opts := map[string]any{"client_secret": secret, "robot_code": ""}
// after
opts := map[string]any{"client_id": clientID, "client_secret": secret} // robot_code defaults to client_id Defensive patterns
Strategy: validation
Validate before calling
func validateDingtalkRobot(opts map[string]any) error {
id, _ := opts["client_id"].(string)
rc, _ := opts["robot_code"].(string)
if id == "" && rc == "" {
return fmt.Errorf("dingtalk: provide robot_code or client_id")
}
return nil
} Type guard
func optString(opts map[string]any, key string) (string, bool) {
s, ok := opts[key].(string)
return s, ok && s != ""
} Prevention
- Always set client_id — it doubles as the robot code fallback
- Never set robot_code to "" explicitly to disable it
- Document in your config template which fields are required
When it happens
Trigger: dingtalk.New(opts) where 'robot_code' is absent/empty AND the fallback source 'client_id' is also empty (or not a string). Notably unreachable when client_id is valid, since robotCode falls back to it.
Common situations: Config with only client_secret set; client_id misspelled or typed as a non-string; robot_code explicitly set to "" in an attempt to 'disable' it while credentials are also incomplete.
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
- dingtalk: client_id and client_secret are required
- tmux: 'session' option is required (name of the tmux session
- config: relay.visibility must be "full", "summary", or "none
- config: at least one [[projects]] entry is required
- config: %s.name is required
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/1902df2aa9ff1acb.
Report an issue: GitHub.