{"record":{"id":"6d2901d79a4e73fa","repo":"Tichau/FileConverter","slug":"the-conversion-preset-must-be-valid-6d2901","errorCode":null,"errorMessage":"The conversion preset must be valid.","messagePattern":"The conversion preset must be valid\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Application/FileConverter/ConversionJobs/ConversionJob_ExtractCDA.cs","lineNumber":121,"sourceCode":"                return;\n            }\n\n            // Generate intermediate file path.\n            string fileName = Path.GetFileName(this.OutputFilePath);\n            string tempPath = Path.GetTempPath();\n            this.intermediateFilePath = PathHelpers.GenerateUniquePath(tempPath + fileName + \".wav\");\n\n            // Sub conversion job (for compression).\n            this.compressionConversionJob = ConversionJobFactory.Create(this.ConversionPreset, this.intermediateFilePath);\n            this.compressionConversionJob.PrepareConversion(this.OutputFilePath);\n            this.compressionThread = Helpers.InstantiateThread(\"CDACompressionThread\", this.CompressAsync);\n        }\n\n        protected override void Convert()\n        {\n            if (this.ConversionPreset == null)\n            {\n                throw new Exception(\"The conversion preset must be valid.\");\n            }\n\n            Debug.Log(\"Starting CDA extraction.\");\n\n            this.UserState = Properties.Resources.ConversionStateExtraction;\n\n            if (!this.diskDrive.IsCDReady())\n            {\n                this.ConversionFailed(Properties.Resources.ErrorCDDriveNotReady);\n                return;\n            }\n\n            if (!this.diskDrive.Refresh())\n            {\n                Debug.Log(\"Can't refresh CD drive data.\");\n                this.ConversionFailed(Properties.Resources.ErrorCDDriveNotReady);\n                return;\n            }","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/Tichau/FileConverter/blob/6c157a411fb70fb7440d2e3b226042781fd55b15/Application/FileConverter/ConversionJobs/ConversionJob_ExtractCDA.cs#L103-L139","documentation":"ConversionJob_ExtractCDA.Convert() throws Exception when this.ConversionPreset is null before it begins CD-audio ripping (open CDDrive, read the track, write intermediate WAV, then run the compression sub-job). The (preset, inputFilePath) base constructor already rejects null presets, so this guard is reachable in practice only through the parameterless ConversionJob_ExtractCDA() design-mode constructor that leaves ConversionPreset null, or via reflection/direct invocation of the protected Convert(). The ExtractCDA Initialize() at line 50 also re-checks, so the same invariant is enforced at both phases.","triggerScenarios":"A ConversionJob_ExtractCDA created via its parameterless ctor has Convert() called; or reflection invokes Convert() on an instance whose preset was never set. Because the ripping path allocates a CDDrive and a compression ConversionJob from this.ConversionPreset, a null preset would NRE further down, so the guard fails fast.","commonSituations":"Design-time instantiation of the CDA job; a test harness exercising Convert() directly; conversion pipeline code that created the job before confirming the .cda input resolved to a loaded preset.","solutions":["Use new ConversionJob_ExtractCDA(conversionPreset, inputFilePath) so the base ctor validates the preset immediately.","Route execution through PrepareConversion() + StartConversion() instead of calling Convert() directly.","In design-time only contexts, early-return when ConversionPreset is null.","Verify the preset object is non-null after loading from user settings before passing it to the factory."],"exampleFix":"// before\nvar job = new ConversionJob_ExtractCDA();\njob.Convert(); // throws: preset null\n\n// after\nvar job = new ConversionJob_ExtractCDA(conversionPreset, inputFilePath);\njob.PrepareConversion(outputFilePath);\njob.StartConversion();","handlingStrategy":"validation","validationCode":"if (job == null || job.ConversionPreset == null)\n{\n    throw new InvalidOperationException(\n        \"ConversionJob_ExtractCDA requires a non-null ConversionPreset; use the (preset, inputFilePath) constructor.\");\n}\njob.StartConversion();","typeGuard":"private static bool HasValidPreset(ConversionJob job) => job != null && job.ConversionPreset != null;","tryCatchPattern":"try\n{\n    job.StartConversion();\n}\ncatch (Exception ex) when (ex.Message.Contains(\"conversion preset must be valid\"))\n{\n    logger.Error(ex, \"CDA job created without a preset.\");\n    job = new ConversionJob_ExtractCDA(LoadPreset(), inputPath);\n}","preventionTips":["Build CDA jobs only via the (preset, inputFilePath) ctor or ConversionJobFactory.Create.","Confirm the .cda input resolves to a loaded preset before job creation.","Do not call Convert() directly; use StartConversion().","Treat the parameterless ctor as design-time only."],"tags":["csharp","fileconverter","conversion-preset","null-check","defensive-guard","cda","cd-audio"],"backgroundTag":null,"analyzedSha":"6c157a411fb70fb7440d2e3b226042781fd55b15","analyzedAt":"2026-08-13T15:04:08.307Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}