{"record":{"id":"03bd22e875c64500","repo":"XTLS/Xray-core","slug":"empty-attr","errorCode":null,"errorMessage":"empty attr","messagePattern":"empty attr","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/geodata/rule_parser.go","lineNumber":204,"sourceCode":"\t\t}\n\t\tdomainRules = append(domainRules, &DomainRule{Value: rule})\n\t}\n\n\treturn domainRules, nil\n}\n\nfunc parseGeoSiteRule(rule string) (*DomainRule_Geosite, error) {\n\tfile, codeWithAttrs, ok := strings.Cut(rule, \":\")\n\tif !ok {\n\t\treturn nil, errors.New(\"syntax error\")\n\t}\n\n\tif file == \"\" {\n\t\treturn nil, errors.New(\"empty file\")\n\t}\n\n\tif strings.HasSuffix(codeWithAttrs, \"@\") || strings.Contains(codeWithAttrs, \"@@\") {\n\t\treturn nil, errors.New(\"empty attr\")\n\t}\n\tcode, attrs, _ := strings.Cut(codeWithAttrs, \"@\")\n\n\tif code == \"\" {\n\t\treturn nil, errors.New(\"empty code\")\n\t}\n\tcode = strings.ToUpper(code)\n\n\tif err := checkFile(file, code); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &DomainRule_Geosite{\n\t\tGeosite: &GeoSiteRule{\n\t\t\tFile:  file,\n\t\t\tCode:  code,\n\t\t\tAttrs: strings.ToLower(attrs),\n\t\t},","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/common/geodata/rule_parser.go#L186-L222","documentation":"A geosite rule's attribute selector is malformed: the code segment ends with '@' (no attribute name after it) or contains '@@' (empty attribute between two '@'). Attributes are the '@attr' suffix on geosite codes.","triggerScenarios":"Rules like \"geosite:cn@\" (trailing @), \"geosite:cn@@ads\", \"ext:gs.dat:cn@\".","commonSituations":"Intent to filter by attribute (e.g. geosite:cn@ads) but the attribute name was deleted or doubled.","solutions":["Either remove the '@' entirely (match whole category) or supply a valid attribute: \"geosite:cn@ads\".","Check the dat file's attribute list (v2fly community dat exposes attrs like @ads/@cn) to confirm the attr name exists."],"exampleFix":"// before\n\"domain\": [\"geosite:cn@\"]\n\n// after\n\"domain\": [\"geosite:cn@ads\"]","handlingStrategy":"validation","validationCode":"if strings.HasSuffix(code, \"@\") || strings.Contains(code, \"@@\") { return fmt.Errorf(\"%q: empty attribute\", r) }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify attribute names against the dat file's published attr list (e.g. @ads); keep exactly one '@' with a non-empty name."],"tags":["geodata","domain-rule","attributes","xray"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}