{"record":{"id":"3bc868449793cab2","repo":"XTLS/Xray-core","slug":"vless-users-invalid-user","errorCode":null,"errorMessage":"VLESS users: invalid user","messagePattern":"VLESS users: invalid user","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/vless.go","lineNumber":59,"sourceCode":"\n// Build implements Buildable\nfunc (c *VLessInboundConfig) Build() (proto.Message, error) {\n\tconfig := new(inbound.Config)\n\n\tif c.Clients != nil {\n\t\tc.Users = c.Clients\n\t}\n\tconfig.Users = make([]*protocol.User, len(c.Users))\n\tswitch c.Flow {\n\tcase vless.XRV, \"\":\n\tdefault:\n\t\treturn nil, errors.New(`VLESS \"settings.flow\" doesn't support \"` + c.Flow + `\" in this version`)\n\t}\n\tprocessClient := func(idx int) error {\n\t\trawUser := c.Users[idx]\n\t\tuser := new(protocol.User)\n\t\tif err := json.Unmarshal(rawUser, user); err != nil {\n\t\t\treturn errors.New(`VLESS users: invalid user`).Base(err)\n\t\t}\n\t\taccount := new(vless.Account)\n\t\tif err := json.Unmarshal(rawUser, account); err != nil {\n\t\t\treturn errors.New(`VLESS users: invalid user`).Base(err)\n\t\t}\n\n\t\tu, err := uuid.ParseString(account.Id)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\taccount.Id = u.String()\n\n\t\tswitch account.Flow {\n\t\tcase \"\":\n\t\t\taccount.Flow = c.Flow\n\t\tcase vless.XRV:\n\t\tdefault:\n\t\t\treturn errors.New(`VLESS users: \"flow\" doesn't support \"` + account.Flow + `\" in this version`)","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/vless.go#L41-L77","documentation":"Thrown inside the per-client loop of a VLESS inbound when a raw user JSON object fails to unmarshal into protocol.User (the generic user record with email/level). This almost always means the clients entry is not a JSON object with compatible fields — wrong type for email/level, or the entry itself is a string/array.","triggerScenarios":"A \"clients\" entry like { \"id\": \"...\", \"level\": \"high\" } (level must be a number) or \"clients\": [\"uuid-string\"] (bare string instead of object). The error is wrapped as 'VLESS users: invalid user' with the underlying JSON error attached.","commonSituations":"Pasting a bare UUID list instead of client objects, or quoting numeric fields during YAML→JSON conversion.","solutions":["Make each clients entry an object: { \"id\": \"<uuid>\", \"email\": \"optional\", \"level\": 0 }","Keep level as a JSON number and email as a string","Read the wrapped base error — it names the exact offending field"],"exampleFix":"// before\n\"clients\": [ \"8c1f4b1a-...\" ]\n// after\n\"clients\": [ { \"id\": \"8c1f4b1a-...\", \"level\": 0 } ]","handlingStrategy":"validation","validationCode":"// each clients entry must be an object with string email and numeric level (both optional)\nfor _, c := range clients {\n    if !gjson.Valid(c.Raw) || c.Type != gjson.JSON {\n        return errors.New(\"each vless client must be a JSON object\")\n    }\n    if e := gjson.Get(c.Raw, \"email\"); e.Exists() && e.Type != gjson.String {\n        return errors.New(\"client email must be a string\")\n    }\n    if l := gjson.Get(c.Raw, \"level\"); l.Exists() && l.Type != gjson.Number {\n        return errors.New(\"client level must be a number\")\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never put bare UUID strings in clients; always wrap in objects","Check the wrapped base error message for the exact field at fault"],"tags":["config","vless","json","users"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}