{"record":{"id":"1902df2aa9ff1acb","repo":"chenhg5/cc-connect","slug":"dingtalk-robot-code-is-required-or-client-id","errorCode":null,"errorMessage":"dingtalk: robot_code is required (or client_id)","messagePattern":"dingtalk: robot_code is required \\(or client_id\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/dingtalk/dingtalk.go","lineNumber":112,"sourceCode":"\tdegradeMu       sync.Mutex\n}\n\nfunc New(opts map[string]any) (core.Platform, error) {\n\tclientID, _ := opts[\"client_id\"].(string)\n\tclientSecret, _ := opts[\"client_secret\"].(string)\n\trobotCode, _ := opts[\"robot_code\"].(string)\n\tallowFrom, _ := opts[\"allow_from\"].(string)\n\tcore.CheckAllowFrom(\"dingtalk\", allowFrom)\n\tshareSessionInChannel, _ := opts[\"share_session_in_channel\"].(bool)\n\tif clientID == \"\" || clientSecret == \"\" {\n\t\treturn nil, fmt.Errorf(\"dingtalk: client_id and client_secret are required\")\n\t}\n\tif robotCode == \"\" {\n\t\trobotCode = clientID // fallback to client_id if robot_code not specified\n\t}\n\t// Validate robot_code format (should not be empty after fallback)\n\tif robotCode == \"\" {\n\t\treturn nil, fmt.Errorf(\"dingtalk: robot_code is required (or client_id)\")\n\t}\n\n\treactionEmoji, _ := opts[\"reaction_emoji\"].(string)\n\treactionEmoji = strings.TrimSpace(reactionEmoji)\n\tif reactionEmoji == \"\" {\n\t\treactionEmoji = defaultReactionEmoji\n\t}\n\tif strings.EqualFold(reactionEmoji, \"none\") {\n\t\treactionEmoji = \"\"\n\t}\n\tdoneEmoji, _ := opts[\"done_emoji\"].(string)\n\tdoneEmoji = strings.TrimSpace(doneEmoji)\n\tif strings.EqualFold(doneEmoji, \"none\") {\n\t\tdoneEmoji = \"\"\n\t}\n\n\t// agent_id is required for work notifications API (numeric type)\n\t// Try to read as int64 first, then float64 (JSON numbers), fallback to 0","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/dingtalk/dingtalk.go#L94-L130","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nopts := map[string]any{\"client_secret\": secret, \"robot_code\": \"\"}\n// after\nopts := map[string]any{\"client_id\": clientID, \"client_secret\": secret} // robot_code defaults to client_id","handlingStrategy":"validation","validationCode":"func validateDingtalkRobot(opts map[string]any) error {\n    id, _ := opts[\"client_id\"].(string)\n    rc, _ := opts[\"robot_code\"].(string)\n    if id == \"\" && rc == \"\" {\n        return fmt.Errorf(\"dingtalk: provide robot_code or client_id\")\n    }\n    return nil\n}","typeGuard":"func optString(opts map[string]any, key string) (string, bool) {\n    s, ok := opts[key].(string)\n    return s, ok && s != \"\"\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["dingtalk","config","validation"],"backgroundTag":"missing-required-config-field","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}