{"record":{"id":"7e638914f0b9dd65","repo":"XTLS/Xray-core","slug":"grid-d-has-no-uniquely-decodable-clue-set","errorCode":null,"errorMessage":"grid %d has no uniquely decodable clue set","messagePattern":"grid (.+?) has no uniquely decodable clue set","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"transport/internet/finalmask/sudoku/table.go","lineNumber":475,"sourceCode":"\t\t\t\tclueGroup(g, ps[3]),\n\t\t\t}\n\t\t\tgroups = sort4(groups)\n\t\t\tkey := packKey(groups)\n\t\t\tkeys[gi] = key\n\t\t\tgroupsByGrid[gi] = groups\n\t\t\tcounts[key]++\n\t\t}\n\n\t\tfor gi, key := range keys {\n\t\t\tif counts[key] == 1 {\n\t\t\t\tpatterns[gi] = append(patterns[gi], groupsByGrid[gi])\n\t\t\t}\n\t\t}\n\t}\n\n\tfor gi, list := range patterns {\n\t\tif len(list) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"grid %d has no uniquely decodable clue set\", gi)\n\t\t}\n\t}\n\n\treturn patterns, nil\n}\n\nfunc clueGroup(g grid, pos byte) byte {\n\t// 2 bits of value + 4 bits of position.\n\treturn ((g[pos] - 1) << 4) | (pos & 0x0f)\n}\n\nfunc generateAllGrids() []grid {\n\tgrids := make([]grid, 0, 288)\n\tvar g grid\n\n\tvar dfs func(idx int)\n\tdfs = func(idx int) {\n\t\tif idx == 16 {","sourceCodeStart":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/transport/internet/finalmask/sudoku/table.go#L457-L493","documentation":"Thrown by getBasePatterns during base pattern construction: after filtering, at least one grid ended up with zero uniquely decodable clue sets (a set whose packed key appears exactly once across all grids). Uniqueness is required so the decoder can map a received hint tuple back to one byte, so an empty grid aborts table generation.","triggerScenarios":"The cross-grid dedup filter removing every candidate for some grid, which depends only on the layout (not the password). Indicates the current layout/hint encoding leaves some grid without any unique signature.","commonSituations":"Custom layouts that compress hint information too aggressively; upstream changes to the key packing or clue enumeration. Not password-dependent, so changing the password does not help.","solutions":["Remove customTable and use the default entropy layout.","Update to a version where the layout and pattern generator are consistent.","Report the failing pattern upstream, since this is a layout-level defect."],"exampleFix":"// before\n\"customTable\": \"xxvvppvv\"\n// after\n\"customTable\": \"\"","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"layout, err := resolveLayout(mode, customTable)\nif err == nil {\n\t_, err = buildTable(password, layout) // dry-run exposes getBasePatterns errors\n}\nif err != nil && strings.Contains(err.Error(), \"uniquely decodable\") {\n\tlayout, _ = resolveLayout(\"prefer_entropy\", \"\")\n}","preventionTips":["This error is layout-dependent, not password-dependent; changing the password will not help.","Stick to layouts validated by the project unless you can run the full uniqueness test yourself."],"tags":["finalmask","sudoku","internal-invariant"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}