{"record":{"id":"50e6c44bcbec46f2","repo":"vxcontrol/pentagi","slug":"msglogs-invalidrequest","errorCode":"Msglogs.InvalidRequest","errorMessage":"group field not found","messagePattern":"group field not found","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"backend/pkg/server/services/msglogs.go","lineNumber":101,"sourceCode":"\t\t}\n\t} else if slices.Contains(privs, \"msglogs.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 = msglogs.flow_id\").\n\t\t\t\tWhere(\"f.user_id = ?\", 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(\"msglogs\", msglogsSQLMappers)\n\n\tif query.Group != \"\" {\n\t\tif _, ok := msglogsSQLMappers[query.Group]; !ok {\n\t\t\tlogger.FromContext(c).Errorf(\"error finding msglogs grouped: group field not found\")\n\t\t\tresponse.Error(c, response.ErrMsglogsInvalidRequest, errors.New(\"group field not found\"))\n\t\t\treturn\n\t\t}\n\n\t\tvar respGrouped msglogsGrouped\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 msglogs 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.MsgLogs, scope); err != nil {\n\t\tlogger.FromContext(c).WithError(err).Errorf(\"error finding msglogs\")\n\t\tresponse.Error(c, response.ErrInternal, err)\n\t\treturn","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/server/services/msglogs.go#L83-L119","documentation":"GetMsglogs supports grouped queries over message logs. When query.Group names a field absent from msglogsSQLMappers, the handler returns this Msglogs.InvalidRequest error, keeping GROUP BY limited to whitelisted columns in the same pattern as flows and knowledge services.","triggerScenarios":"GET msglogs list endpoint with ?group=<field> where <field> is not a key in msglogsSQLMappers (typo, wrong casing, or field that exists in another service's mappers but not here).","commonSituations":"Dashboard widgets sharing a grouping component across flows/knowledge/msglogs with a hardcoded field name; renamed log fields after an upgrade; clients guessing groupable fields like 'agent' when the mapper key is different.","solutions":["Use a group field present in msglogsSQLMappers (see pkg/server/services/msglogs.go).","Verify the group value against the current mapper keys after any upgrade that touched message-log fields.","Make the shared UI component accept a per-service list of groupable fields.","Extend msglogsSQLMappers if a new grouping dimension is truly required."],"exampleFix":"// before\nGET /msglogs?group=message_type\n// after\nGET /msglogs?group=type","handlingStrategy":"validation","validationCode":"const MSGLOG_GROUPS = ['type','created_at','flow_id']; // mirror msglogsSQLMappers\nif (group && !MSGLOG_GROUPS.includes(group)) {\n  throw new Error(`group field not found: ${group}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const logs = await getMsglogs({ group });\n  render(logs);\n} catch (e) {\n  if (e.code === 'Msglogs.InvalidRequest' && /group field not found/.test(e.message)) {\n    setGroup(null);\n    notify('Grouping not supported for this field; showing flat log list.');\n  } else { throw e; }\n}","preventionTips":["Derive groupable fields from msglogsSQLMappers rather than guessing.","Keep per-service group option lists in a shared config.","Re-validate group params after backend upgrades that touch log fields.","Add API tests for every grouping option the UI offers."],"tags":["validation","query-params","sql"],"backgroundTag":"invalid-group-field","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}