{"record":{"id":"c42229a3c4073adf","repo":"SubtitleEdit/subtitleedit","slug":"not-a-waveform-theme-file","errorCode":null,"errorMessage":"Not a waveform theme file.","messagePattern":"Not a waveform theme file\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"warning","filePath":"src/ui/Features/Options/Settings/WaveformThemes/WaveformThemesViewModel.cs","lineNumber":211,"sourceCode":"        });\n\n        if (files.Count == 0)\n        {\n            return;\n        }\n\n        var path = files[0].Path.LocalPath;\n\n        try\n        {\n            await using var stream = File.OpenRead(path);\n            var dto = await JsonSerializer.DeserializeAsync<WaveformThemeDto>(stream, new JsonSerializerOptions\n            {\n                PropertyNameCaseInsensitive = true,\n            });\n            if (dto == null)\n            {\n                throw new InvalidOperationException(\"Not a waveform theme file.\");\n            }\n\n            var theme = dto.ToThemeDisplay(Path.GetFileNameWithoutExtension(path));\n            Themes.Add(theme);\n            SelectedTheme = theme;\n        }\n        catch (Exception exception)\n        {\n            // The user picked this file, so a failure has to be reported - silently doing\n            // nothing looks identical to a successful import of an empty theme.\n            await ShowFileErrorAsync(Se.Language.General.CouldNotOpenFileXErrorY, path, exception);\n        }\n    }\n\n    private async Task ShowFileErrorAsync(string format, string path, Exception exception)\n    {\n        Se.LogError(exception, string.Format(format, path, exception.Message));\n","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Features/Options/Settings/WaveformThemes/WaveformThemesViewModel.cs#L193-L229","documentation":"Thrown by WaveformThemesViewModel.ImportThemeAsync when JsonSerializer.DeserializeAsync<WaveformThemeDto> returns null — i.e. the picked file parsed as valid JSON but to an empty/null token (commonly an empty file, a JSON null, or a JSON array/scalar that does not map onto the DTO). The deserialiser itself did not throw, but there is no theme object to import.","triggerScenarios":"User picks a .seWaveformTheme file via the open-file picker; the stream deserialises without error but dto == null.","commonSituations":"Empty file saved with the theme extension; file contains just `null` or `[]`; file is a different theme/tool's JSON whose root is not a WaveformThemeDto-shaped object; file truncated to zero bytes.","solutions":["Open the .seWaveformTheme file in a text editor and confirm it is a JSON object with Name/TextColor/etc. properties.","Re-export a known-good theme from Subtitle Edit (export theme) and compare the structure.","If the file is empty or `null`, delete it and export a fresh one.","Ensure the file was not corrupted in transit (e.g. git LFS pointer, download truncated)."],"exampleFix":"// the file must look like:\n{\n  \"Name\": \"My Theme\",\n  \"TextColor\": \"#FFFFFFFF\",\n  \"WaveformColor\": \"#FF004600\",\n  \"BackgroundColor\": \"#FF000000\"\n  // ...remaining color properties\n}","handlingStrategy":"validation","validationCode":"// Read and validate the file shape before deserialising\nvar text = await File.ReadAllTextAsync(path);\nif (string.IsNullOrWhiteSpace(text) || text.Trim() == \"null\")\n    throw new InvalidOperationException(\"Not a waveform theme file.\");\nusing var doc = JsonDocument.Parse(text);\nif (doc.RootElement.ValueKind != JsonValueKind.Object)\n    throw new InvalidOperationException(\"Not a waveform theme file.\");","typeGuard":"static async Task<bool> IsWaveformThemeFile(string path) {\n    try { using var doc = JsonDocument.Parse(await File.ReadAllTextAsync(path)); return doc.RootElement.ValueKind == JsonValueKind.Object; }\n    catch { return false; } }","tryCatchPattern":"null","preventionTips":["Export themes from Subtitle Edit as the canonical format.","Reject empty/null files at the picker boundary.","Keep a known-good reference theme to diff against broken imports."],"tags":["subtitle-edit","waveform-themes","json-deserialization","ui","import"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}