{"record":{"id":"2cdb343f88af4e0c","repo":"Flow-Launcher/Flow.Launcher","slug":"failed-to-deserialize-double-pinyin-table-result","errorCode":null,"errorMessage":"Failed to deserialize double pinyin table: result is null","messagePattern":"Failed to deserialize double pinyin table: result is null","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"Flow.Launcher.Infrastructure/PinyinAlphabet.cs","lineNumber":56,"sourceCode":"                        if (_settings.UseDoublePinyin)\n                        {\n                            Reload();\n                        }\n                        break;\n                }\n            };\n        }\n\n        public void Reload()\n        {\n            LoadDoublePinyinTable();\n            _pinyinCache.Clear();\n        }\n\n        private void CreateDoublePinyinTableFromStream(Stream jsonStream)\n        {\n            var table = JsonSerializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(jsonStream) ??\n                throw new InvalidOperationException(\"Failed to deserialize double pinyin table: result is null\");\n\n            var schemaKey = _settings.DoublePinyinSchema.ToString();\n            if (!table.TryGetValue(schemaKey, out var schemaDict))\n            {\n                throw new ArgumentException($\"DoublePinyinSchema '{schemaKey}' is invalid or double pinyin table is broken.\");\n            }\n\n            currentDoublePinyinTable = new ReadOnlyDictionary<string, string>(schemaDict);\n        }\n\n        private void LoadDoublePinyinTable()\n        {\n            if (!_settings.UseDoublePinyin)\n            {\n                currentDoublePinyinTable = new ReadOnlyDictionary<string, string>(new Dictionary<string, string>());\n                return;\n            }\n","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/Flow-Launcher/Flow.Launcher/blob/7fc63b07bbaa10a0f0b2601487913fcba9ed24b0/Flow.Launcher.Infrastructure/PinyinAlphabet.cs#L38-L74","documentation":"Thrown as InvalidOperationException when JsonSerializer.Deserialize of the double-pinyin table JSON returns null — which for a Dictionary target happens only when the JSON stream contains a literal null token (not an empty object). The table is loaded from Resources/double_pinyin.json at the app base directory. LoadDoublePinyinTable does NOT catch this specific exception, so it propagates.","triggerScenarios":"The double_pinyin.json file content is literally the text 'null' (a JSON null token); the stream is positioned such that the first token is null; a manual/automated edit replaced the table contents with null. A missing or malformed-but-non-null file would throw JsonException instead.","commonSituations":"A user or tool overwrote Resources/double_pinyin.json with 'null' while experimenting; a build/packaging step corrupted the resource; a partial file write left only the token 'null'; the resource file was replaced by a placeholder during a failed update.","solutions":["Restore Resources/double_pinyin.json from a known-good Flow Launcher install or the source repo.","Open the file and confirm it is a JSON object like {\"SchemaName\": {\"key\":\"value\"}}, not the literal null.","If customizing, validate the JSON parses to a non-null Dictionary before saving.","Reinstall Flow Launcher to restore shipped resources."],"exampleFix":"// before\nvar table = JsonSerializer.Deserialize<Dictionary<string, Dictionary<string,string>>>(jsonStream)\n    ?? throw new InvalidOperationException(\"Failed to deserialize double pinyin table: result is null\");\n\n// after — treat null as empty and warn, so the feature degrades instead of crashing\nvar table = JsonSerializer.Deserialize<Dictionary<string, Dictionary<string,string>>>(jsonStream)\n    ?? new Dictionary<string, Dictionary<string,string>>();\nif (table.Count == 0)\n    Log.Warn(nameof(PinyinAlphabet), \"Double pinyin table was null/empty; feature disabled\");","handlingStrategy":"validation","validationCode":"var raw = File.ReadAllText(tablePath);\nif (string.IsNullOrWhiteSpace(raw) || raw.Trim() == \"null\")\n{ Log.Warn(...); currentDoublePinyinTable = Empty; return; }","typeGuard":"null","tryCatchPattern":"try { CreateDoublePinyinTableFromStream(fs); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"result is null\"))\n{ Log.Exception(...); currentDoublePinyinTable = Empty; }","preventionTips":["Do not overwrite Resources/double_pinyin.json with 'null' or empty content.","Validate the JSON is a non-null object before saving.","Restore the shipped resource if customization goes wrong.","Unit-test deserialization of the resource on build."],"tags":["pinyin","json","config","deserialization"],"backgroundTag":null,"analyzedSha":"7fc63b07bbaa10a0f0b2601487913fcba9ed24b0","analyzedAt":"2026-08-13T14:54:20.914Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}