{"record":{"id":"f82242aa0856cb3a","repo":"vxcontrol/pentagi","slug":"prompts-invalidrequest","errorCode":"Prompts.InvalidRequest","errorMessage":"group field not found","messagePattern":"group field not found","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"backend/pkg/server/services/prompts.go","lineNumber":90,"sourceCode":"\n\tprivs := c.GetStringSlice(\"prm\")\n\tif !slices.Contains(privs, \"settings.prompts.view\") {\n\t\tlogger.FromContext(c).Errorf(\"error filtering user role permissions: permission not found\")\n\t\tresponse.Error(c, response.ErrNotPermitted, nil)\n\t\treturn\n\t}\n\n\tuid := c.GetUint64(\"uid\")\n\tscope := func(db *gorm.DB) *gorm.DB {\n\t\treturn db.Where(\"user_id = ?\", uid)\n\t}\n\n\tquery.Init(\"prompts\", promptsSQLMappers)\n\n\tif query.Group != \"\" {\n\t\tif _, ok := promptsSQLMappers[query.Group]; !ok {\n\t\t\tlogger.FromContext(c).Errorf(\"error finding prompts grouped: group field not found\")\n\t\t\tresponse.Error(c, response.ErrPromptsInvalidRequest, errors.New(\"group field not found\"))\n\t\t\treturn\n\t\t}\n\n\t\tvar respGrouped promptsGrouped\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 prompts 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.Prompts, scope); err != nil {\n\t\tlogger.FromContext(c).WithError(err).Errorf(\"error finding prompts\")\n\t\tresponse.Error(c, response.ErrInternal, err)\n\t\treturn","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/server/services/prompts.go#L72-L108","documentation":"GetPrompts lists prompts and supports grouping via the `group` query parameter. The value must exist in `promptsSQLMappers`, the allowlist of fields permitted for GROUP BY (prevents SQL injection and invalid columns). An unmapped value causes this Prompts.InvalidRequest error.","triggerScenarios":"GET prompts endpoint with `group=<name>` where `<name>` is not a key in `promptsSQLMappers` — e.g. a typo, an internal column name, or a field not registered for grouping.","commonSituations":"Frontend dropdown out of sync with backend mapper; user hand-crafts the API call; a renamed field after a backend update still sent by an older client.","solutions":["Use a group value exactly matching a key in `promptsSQLMappers` in backend/pkg/server/services/prompts.go","Drop the `group` query parameter to get the ungrouped list","To group by a new field, register it in `promptsSQLMappers`"],"exampleFix":"// before\nGET /api/v1/prompts?group=prompttext\n// after\nGET /api/v1/prompts?group=prompt_text","handlingStrategy":"validation","validationCode":"const allowed = new Set(['name','type','created_at']); // mirror promptsSQLMappers keys\nif (group && !allowed.has(group)) throw new Error(`invalid group field: ${group}`);","typeGuard":"function isValidPromptsGroup(v: string, allowed: readonly string[]): v is typeof allowed[number] {\n  return (allowed as readonly string[]).includes(v);\n}","tryCatchPattern":"try {\n  const res = await api.get('/prompts', { params: group ? { group } : {} });\n} catch (e) {\n  if (e.response?.data?.code === 'Prompts.InvalidRequest') {\n    // fall back to ungrouped listing\n  }\n}","preventionTips":["Whitelist group fields client-side mirroring promptsSQLMappers","Regenerate shared API types after backend changes","Avoid free-text group values"],"tags":["rest","validation","group-by"],"backgroundTag":"invalid-group-field","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}