{"record":{"id":"35e336eab493d579","repo":"vxcontrol/pentagi","slug":"errusersinvalidrequest","errorCode":"ErrUsersInvalidRequest","errorMessage":"group field not found","messagePattern":"group field not found","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"backend/pkg/server/services/users.go","lineNumber":353,"sourceCode":"\t\tresponse.Error(c, response.ErrUsersInvalidRequest, err)\n\t\treturn\n\t}\n\n\tuid := c.GetUint64(\"uid\")\n\tprivs := c.GetStringSlice(\"prm\")\n\tscope := func(db *gorm.DB) *gorm.DB {\n\t\tif !slices.Contains(privs, \"users.view\") {\n\t\t\treturn db.Where(\"id = ?\", uid)\n\t\t}\n\t\treturn db\n\t}\n\n\tquery.Init(\"users\", usersSQLMappers)\n\n\tif query.Group != \"\" {\n\t\tif _, ok := usersSQLMappers[query.Group]; !ok {\n\t\t\tlogger.FromContext(c).Errorf(\"error finding users grouped: group field not found\")\n\t\t\tresponse.Error(c, response.ErrUsersInvalidRequest, errors.New(\"group field not found\"))\n\t\t\treturn\n\t\t}\n\n\t\tvar respGrouped usersGrouped\n\t\tif respGrouped.Total, err = query.QueryGrouped(s.db, &respGrouped.Grouped, scope); err != nil {\n\t\t\tlogger.FromContext(c).WithError(err).Errorf(\"error finding users grouped\")\n\t\t\tresponse.Error(c, response.ErrInternal, err)\n\t\t\treturn\n\t\t}\n\n\t\tresponse.Success(c, http.StatusOK, respGrouped)\n\t\treturn\n\t}\n\n\tif resp.Total, err = query.Query(s.db, &resp.Users, scope); err != nil {\n\t\tlogger.FromContext(c).WithError(err).Errorf(\"error finding users\")\n\t\tresponse.Error(c, response.ErrInternal, err)\n\t\treturn","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/server/services/users.go#L335-L371","documentation":"GetUsers validates the `group` query parameter against usersSQLMappers before running a grouped query. If the value is not a registered mapping key, the handler returns ErrUsersInvalidRequest with message 'group field not found', refusing to build a GROUP BY on an unknown column.","triggerScenarios":"GET /users?group=<field> where <field> is missing from usersSQLMappers — typo, renamed field, or a column never whitelisted for grouping.","commonSituations":"Client code written against outdated docs, dashboards persisting old group params, or new user columns added without mapper registration.","solutions":["Use one of the keys defined in usersSQLMappers in backend/pkg/server/services/users.go","Correct the group parameter in the request","Add the field to usersSQLMappers if grouped user statistics are required","Regenerate/update frontend types so only valid group fields are offered"],"exampleFix":"// before\nGET /api/v1/users?group=rolle\n// after\nGET /api/v1/users?group=role","handlingStrategy":"validation","validationCode":"const USER_GROUPS = ['role','status','created_at']; // mirror usersSQLMappers\nif (group && !USER_GROUPS.includes(group)) throw new Error(`invalid group: ${group}`);\nawait api.get(`/users?group=${encodeURIComponent(group)}`);","typeGuard":"function isUserGroupField(v: unknown): v is string {\n  return typeof v === 'string' && ['role','status','created_at'].includes(v);\n}","tryCatchPattern":"try {\n  return await api.getUsers({ group });\n} catch (e) {\n  if (e.response?.data?.code === 'ErrUsersInvalidRequest') {\n    console.warn(`group '${group}' rejected; defaulting to role`);\n    return api.getUsers({ group: 'role' });\n  }\n  throw e;\n}","preventionTips":["Mirror mapper keys into generated client constants","Restrict grouping UI to whitelisted options","Add contract tests that exercise every group key","Update dashboards when mapper fields are renamed"],"tags":["api","validation","grouping"],"backgroundTag":"invalid-query-parameter","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}