{"record":{"id":"0088f29d5a23e793","repo":"iflytek/astron-agent","slug":"request-id-must-not-been-empty","errorCode":null,"errorMessage":"request_id must not been empty","messagePattern":"request_id must not been empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tenant/internal/handler/req.go","lineNumber":73,"sourceCode":"\tCloudId   string `json:\"cloud_id\"`\n}\n\ntype AddAppReq struct {\n\tRequestId string `json:\"request_id\"`\n\tAppName   string `json:\"app_name\"`\n\tAppDesc   string `json:\"app_desc\"`\n\tDevId     int64  `json:\"dev_id\"`\n\tCloudId   string `json:\"cloud_id\"`\n}\n\nfunc newAddAppReq(c *gin.Context) (*AddAppReq, error) {\n\treq := &AddAppReq{}\n\terr := c.BindJSON(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(req.RequestId) == 0 {\n\t\treturn nil, errors.New(\"request_id must not been empty\")\n\t}\n\tif len(req.AppName) == 0 {\n\t\treturn nil, errors.New(\"app_name must not been empty\")\n\t}\n\tif req.DevId <= 0 {\n\t\treturn nil, errors.New(\"dev_id must been more than zero\")\n\t}\n\tif len(req.CloudId) == 0 {\n\t\treturn nil, errors.New(\"cloud_id must not been empty\")\n\t}\n\tif len(req.AppDesc) == 0 {\n\t\treq.AppDesc = \"\"\n\t}\n\treturn req, nil\n}\n\ntype ModifyAppReq struct {\n\tRequestId string `json:\"request_id\"`","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/tenant/internal/handler/req.go#L55-L91","documentation":"newAddAppReq parses the JSON body of the add-app request and requires a non-empty RequestId; an empty request_id fails validation. The request id is used for idempotency/tracing of app-creation calls, so it must be supplied by the client.","triggerScenarios":"POST add-app endpoint (SaveApp handler) with a JSON body whose request_id field is absent, empty string, or with mismatched JSON field casing so it unmarshals to empty.","commonSituations":"Client generating request_id only on retries instead of always; JSON tags renamed after an API update so the client's old field name no longer maps; tests/fixtures omitting request_id; proxies re-serializing bodies and dropping fields.","solutions":["Include a non-empty request_id (e.g. UUID) in the request JSON body","Verify the JSON field name/case matches the AddAppReq struct binding tag (e.g. \"request_id\")","Regenerate/update the client SDK or fixtures after API struct changes"],"exampleFix":"// before\n{\"app_name\":\"myapp\",\"dev_id\":3,\"cloud_id\":\"c1\"}\n// after\n{\"request_id\":\"3f2c1a9e-8b4d-4e6f-9a01-77c2d5e8f910\",\"app_name\":\"myapp\",\"dev_id\":3,\"cloud_id\":\"c1\"}","handlingStrategy":"validation","validationCode":"if req.RequestId == \"\" {\n    return errors.New(\"request_id is required\")\n}\nbody, _ := json.Marshal(req)\n_ = body","typeGuard":null,"tryCatchPattern":"resp, err := http.Post(addAppURL, \"application/json\", bytes.NewReader(payload))\nif err == nil && resp.StatusCode >= 400 {\n    body, _ := io.ReadAll(resp.Body)\n    if strings.Contains(string(body), \"request_id must not been empty\") {\n        payload.RequestId = uuid.NewString()\n        // rebuild and retry once\n    }\n}","preventionTips":["Always generate a UUID request_id for every add-app call","Validate required fields client-side before serializing the payload","Match JSON key casing to the server struct binding tags","Update client SDKs/fixtures when AddAppReq fields change"],"tags":["go","gin","api","validation","json"],"backgroundTag":"empty-required-field","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"}