{"record":{"id":"b3c856380b855212","repo":"iflytek/astron-agent","slug":"name-or-app-ids-param-must-have-at-least-one","errorCode":null,"errorMessage":"name or app_ids param must have at least one","messagePattern":"name or app_ids param must have at least one","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tenant/internal/handler/req.go","lineNumber":24,"sourceCode":"\t\"strings\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\ntype AppListReq struct {\n\tName    string\n\tAppIds  []string\n\tDevId   int\n\tCloudId string\n}\n\nfunc newAppListReq(c *gin.Context) (*AppListReq, error) {\n\tname, _ := c.GetQuery(\"name\")\n\tappIds, _ := c.GetQuery(\"app_ids\")\n\tcloudId, _ := c.GetQuery(\"cloud_id\")\n\tdevId, _ := c.GetQuery(\"dev_id\")\n\tif len(name) == 0 && len(appIds) == 0 {\n\t\treturn nil, errors.New(\"name or app_ids param must have at least one\")\n\t}\n\n\treq := &AppListReq{\n\t\tName:    name,\n\t\tCloudId: cloudId,\n\t}\n\n\tif len(appIds) > 0 {\n\t\treq.AppIds = strings.Split(appIds, \",\")\n\t}\n\n\tif len(devId) > 0 {\n\t\tdevIdInt, err := strconv.Atoi(devId)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treq.DevId = devIdInt\n\t}","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/tenant/internal/handler/req.go#L6-L42","documentation":"newAppListReq requires at least one of the 'name' or 'app_ids' query parameters when listing apps; calling the list endpoint with neither returns this validation error. It prevents unbounded full-table app scans through the API.","triggerScenarios":"GET app list/detail endpoint (handled by ListApp or DetailApp) called without both ?name= and ?app_ids= query parameters.","commonSituations":"Frontend/client sending an empty filter form; API migration dropping the old required query param; hand-written curl/Postman calls omitting filters; proxy stripping empty query parameters.","solutions":["Add ?name=<search> or ?app_ids=<comma-or-list-of-ids> to the request URL","Fix the calling client to include the filter it intends (check request building code)","If a full listing is legitimately needed, use a dedicated admin/list API instead of this filtered endpoint"],"exampleFix":"// before\nGET /api/v1/apps\n// after\nGET /api/v1/apps?app_ids=1001,1002\n// or\nGET /api/v1/apps?name=myapp","handlingStrategy":"validation","validationCode":"if name == \"\" && appIds == \"\" {\n    return errors.New(\"either name or app_ids query parameter is required\")\n}\nurl := fmt.Sprintf(\"/api/v1/apps?app_ids=%s\", url.QueryEscape(appIds))","typeGuard":null,"tryCatchPattern":"resp, err := http.Get(listURL)\nif err == nil && resp.StatusCode == http.StatusBadRequest {\n    body, _ := io.ReadAll(resp.Body)\n    if strings.Contains(string(body), \"name or app_ids param must have at least one\") {\n        // add the missing filter and retry\n    }\n}","preventionTips":["Always send at least one filter (name or app_ids) when calling the app list API","Build query parameters in the client so empty filters are caught before the request","Keep API client SDKs in sync with required-parameter changes","For unfiltered listings, use the appropriate admin endpoint instead"],"tags":["go","gin","api","validation","query-params"],"backgroundTag":"missing-required-argument","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}