{"record":{"id":"832458ef9399698c","repo":"MHSanaei/3x-ui","slug":"missing-required-user-field-q","errorCode":null,"errorMessage":"missing required user field %q","messagePattern":"missing required user field %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xray/api.go","lineNumber":63,"sourceCode":"var (\n\ttrafficRegex       = regexp.MustCompile(`(inbound|outbound)>>>([^>]+)>>>traffic>>>(downlink|uplink)`)\n\tclientTrafficRegex = regexp.MustCompile(`user>>>([^>]+)>>>traffic>>>(downlink|uplink)`)\n)\n\n// XrayAPI is a gRPC client for managing Xray core configuration, inbounds, outbounds, and statistics.\ntype XrayAPI struct {\n\tHandlerServiceClient *command.HandlerServiceClient\n\tStatsServiceClient   *statsService.StatsServiceClient\n\tRoutingServiceClient *routerService.RoutingServiceClient\n\tgrpcClient           *grpc.ClientConn\n\tisConnected          bool\n\tStatsLastValues      map[string]int64\n}\n\nfunc getRequiredUserString(user map[string]any, key string) (string, error) {\n\tvalue, ok := user[key]\n\tif !ok || value == nil {\n\t\treturn \"\", fmt.Errorf(\"missing required user field %q\", key)\n\t}\n\n\tstrValue, ok := value.(string)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"invalid type for user field %q: %T\", key, value)\n\t}\n\n\treturn strValue, nil\n}\n\nfunc getOptionalUserString(user map[string]any, key string) (string, error) {\n\tvalue, ok := user[key]\n\tif !ok || value == nil {\n\t\treturn \"\", nil\n\t}\n\n\tstrValue, ok := value.(string)\n\tif !ok {","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/MHSanaei/3x-ui/blob/ad32144c42455696ea9f14e12168beac3e25f5d2/internal/xray/api.go#L45-L81","documentation":"getRequiredUserString in internal/xray/api.go reports a missing key (or explicit nil value) in the user map used to build Xray protocol accounts for the handler API. Every protocol branch first pulls its mandatory fields — typically 'email' plus protocol-specific ones like 'publicKey' for wireguard — so this error names exactly which field the inbound's client settings lack.","triggerScenarios":"Calling the user-add path (AddUser/AlterInbound construction in api.go) with a client map lacking 'email', a wireguard client without 'publicKey', etc. Concretely: malformed client JSON in the inbound settings, an API/manual insertion that skipped a mandatory field, or a protocol handler expecting a field the stored client model never wrote.","commonSituations":"Hand-edited inbound settings JSON missing a field; a client created through a path that only sets flow/id but not email; wireguard clients created before a version that started requiring publicKey; schema drift between the panel's stored client objects and a newer Xray-core expectation.","solutions":["Inspect the error's %q field name, then open the inbound's client entry in the panel and fill in that exact field (e.g. set the client email / wireguard publicKey) and save, which regenerates the user map.","If the field genuinely exists in the stored JSON, check for a nil value — the guard treats nil the same as missing; remove the null or set a real value.","If the error appears right after a panel upgrade on old inbounds, migrate the stored clients (add the now-required field) rather than hand-patching Xray."],"exampleFix":"// before — client map missing email\nuser := map[string]any{\"id\": uuidStr, \"level\": 0}\n\n// after\nuser := map[string]any{\"email\": \"alice@example.com\", \"id\": uuidStr, \"level\": 0}","handlingStrategy":"validation","validationCode":"// Validate required fields before building the Xray user\nrequired := []string{\"email\"}\nif proto == \"wireguard\" {\n    required = append(required, \"publicKey\")\n}\nfor _, k := range required {\n    if v, ok := user[k]; !ok || v == nil {\n        return fmt.Errorf(\"client settings missing %q\", k)\n    }\n}","typeGuard":"func hasRequiredUserFields(user map[string]any, keys ...string) bool {\n    for _, k := range keys {\n        v, ok := user[k]\n        if !ok || v == nil {\n            return false\n        }\n        if _, isStr := v.(string); !isStr {\n            return false\n        }\n    }\n    return true\n}","tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"missing required user field\") {\n        // extract field name from message, fix client entry in panel, no retry\n    }\n}","preventionTips":["Create clients through the panel UI/API so mandatory fields are enforced at insert.","Validate imported client JSON against the Zod schemas before writing it to the inbound."],"tags":["xray","grpc","validation","user-management"],"backgroundTag":null,"analyzedSha":"ad32144c42455696ea9f14e12168beac3e25f5d2","analyzedAt":"2026-08-15T11:13:23.905Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}