{"record":{"id":"47bc626897cb07a5","repo":"vxcontrol/pentagi","slug":"assistants-invalidrequest","errorCode":"Assistants.InvalidRequest","errorMessage":"group field not found","messagePattern":"group field not found","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"backend/pkg/server/services/assistants.go","lineNumber":130,"sourceCode":"\t\t}\n\t} else if slices.Contains(privs, \"assistants.view\") {\n\t\tscope = func(db *gorm.DB) *gorm.DB {\n\t\t\treturn db.\n\t\t\t\tJoins(\"INNER JOIN flows f ON f.id = assistants.flow_id\").\n\t\t\t\tWhere(\"f.id = ? AND f.user_id = ?\", flowID, uid)\n\t\t}\n\t} else {\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\tquery.Init(\"assistants\", assistantsSQLMappers)\n\n\tif query.Group != \"\" {\n\t\tif _, ok := assistantsSQLMappers[query.Group]; !ok {\n\t\t\tlogger.FromContext(c).Errorf(\"error finding assistants grouped: group field not found\")\n\t\t\tresponse.Error(c, response.ErrAssistantsInvalidRequest, errors.New(\"group field not found\"))\n\t\t\treturn\n\t\t}\n\n\t\tvar respGrouped assistantsGrouped\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 assistants 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.Assistants, scope); err != nil {\n\t\tlogger.FromContext(c).WithError(err).Errorf(\"error finding assistants\")\n\t\tresponse.Error(c, response.ErrInternal, err)\n\t\treturn","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/server/services/assistants.go#L112-L148","documentation":"GetFlowAssistants validates the `group` query parameter against assistantsSQLMappers before running the grouped aggregation. An unrecognized value causes an immediate Assistants.InvalidRequest response with 'group field not found', keeping invalid identifiers out of the generated GROUP BY clause.","triggerScenarios":"GET /flows/{flow_id}/assistants?group=<field> where <field> is not a key in assistantsSQLMappers (typo, wrong casing, or a field that exists on other entities but not assistants).","commonSituations":"Copy-pasting group parameters from container or assistantlog queries; stale frontend constants after a schema change; API consumers guessing field names from the DB schema.","solutions":["Pick a group value present in assistantsSQLMappers in backend/pkg/server/services/assistants.go","Consult the endpoint's Swagger documentation for supported group fields","Drop the group parameter to list assistants without aggregation","Add the field to assistantsSQLMappers in code if aggregation on it is a legitimate requirement"],"exampleFix":"// before\nGET /api/v1/flows/42/assistants?group=worker_type\n// after\nGET /api/v1/flows/42/assistants?group=type  (valid mapper key)","handlingStrategy":"validation","validationCode":"const assistantsGroups = [\"type\",\"status\",\"flow\"];\nif (group && !assistantsGroups.includes(group)) {\n  throw new Error(`group must be one of: ${assistantsGroups.join(', ')}`);\n}","typeGuard":"function isAssistantsGroup(g: string | undefined): g is typeof assistantsGroups[number] {\n  return !!g && (assistantsGroups as string[]).includes(g);\n}","tryCatchPattern":"try {\n  return await api.get(`/flows/${flowId}/assistants`, { params: { group } });\n} catch (e) {\n  if (e.response?.data?.code === 'Assistants.InvalidRequest') {\n    return await api.get(`/flows/${flowId}/assistants`);\n  }\n  throw e;\n}","preventionTips":["Keep per-endpoint group whitelists in one shared file","Log and surface 400 responses with the requested value for fast diagnosis","Document groupable fields in the endpoint's Swagger annotations"],"tags":["api","validation","query-params","grouping"],"backgroundTag":"invalid-group-field","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}