{"record":{"id":"13ce30a5b37b8fd9","repo":"getredash/redash","slug":"group-id-is-invalid","errorCode":null,"errorMessage":"Group id {} is invalid.","messagePattern":"Group id (.+?) is invalid\\.","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"redash/handlers/users.py","lineNumber":232,"sourceCode":"        if \"password\" in params and \"old_password\" not in params:\n            abort(403, message=\"Must provide current password to update password.\")\n\n        if \"old_password\" in params and not user.verify_password(params[\"old_password\"]):\n            abort(403, message=\"Incorrect current password.\")\n\n        if \"password\" in params:\n            user.hash_password(params.pop(\"password\"))\n            params.pop(\"old_password\")\n\n        if \"group_ids\" in params:\n            if not self.current_user.has_permission(\"admin\"):\n                abort(403, message=\"Must be admin to change groups membership.\")\n\n            for group_id in params[\"group_ids\"]:\n                try:\n                    models.Group.get_by_id_and_org(group_id, self.current_org)\n                except NoResultFound:\n                    abort(400, message=\"Group id {} is invalid.\".format(group_id))\n\n            if len(params[\"group_ids\"]) == 0:\n                params.pop(\"group_ids\")\n\n        if \"email\" in params:\n            require_allowed_email(params[\"email\"])\n\n        email_address_changed = \"email\" in params and params[\"email\"] != user.email\n        needs_to_verify_email = email_address_changed and settings.email_server_is_configured()\n        if needs_to_verify_email:\n            user.is_email_verified = False\n\n        try:\n            self.update_model(user, params)\n            models.db.session.commit()\n\n            if needs_to_verify_email:\n                send_verify_email(user, self.current_org)","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/getredash/redash/blob/ca79fe988d81cdac9675b412f3dfcab107bc1fbc/redash/handlers/users.py#L214-L250","documentation":"Raised by the user update endpoint when the request's group_ids array references a group that does not exist within the current organization. The handler verifies each id via models.Group.get_by_id_and_org and aborts with HTTP 400 on the first id that yields NoResultFound.","triggerScenarios":"POST to /api/users/<id> with group_ids containing an id that is deleted, belongs to a different organization, or is a plain typo (e.g. [999]); passing group names or slugs instead of numeric ids also produces it.","commonSituations":"Stale cached group lists after groups were deleted or re-created; scripts copy-pasting group ids between environments (staging vs prod orgs); sending strings like \"group_admin\" instead of the numeric id.","solutions":["Fetch valid ids first via GET /api/groups and use ids from that response","Verify each id exists in the same organization as the user being edited","Drop deleted/stale ids from group_ids before resubmitting"],"exampleFix":"# before\n{\"group_ids\": [1, 999]}  # 400: Group id 999 is invalid.\n# after\ngroups = requests.get(f\"{url}/api/groups\", headers=hdrs).json()\nvalid = {g[\"id\"] for g in groups}\n{\"group_ids\": [g for g in [1, 999] if g in valid]}","handlingStrategy":"validation","validationCode":"valid = {g[\"id\"] for g in requests.get(f\"{url}/api/groups\", headers=hdrs).json()}\npayload[\"group_ids\"] = [gid for gid in payload.get(\"group_ids\", []) if gid in valid]\nif not payload[\"group_ids\"]:\n    payload.pop(\"group_ids\", None)","typeGuard":"def is_valid_group_id(groups, gid):\n    return isinstance(gid, int) and gid in {g[\"id\"] for g in groups}","tryCatchPattern":null,"preventionTips":["Always resolve group ids from GET /api/groups at request time instead of hardcoding","Re-fetch group lists after org/group restructuring","Treat any 400 mentioning 'Group id' as a signal to refresh cached ids"],"tags":["redash","validation","http-400","groups","users"],"backgroundTag":"invalid-reference-id","analyzedSha":"ca79fe988d81cdac9675b412f3dfcab107bc1fbc","analyzedAt":"2026-08-28T18:32:34.637Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}