{"record":{"id":"e498a0647512e006","repo":"itsfatduck/optimizerDuck","slug":"missing-required-originalenabled-in-scheduled-task-revert","errorCode":null,"errorMessage":"Missing required 'OriginalEnabled' in scheduled-task revert data.","messagePattern":"Missing required 'OriginalEnabled' in scheduled-task revert data\\.","errorType":"exception","errorClass":"StepExecutionException","httpStatus":null,"severity":"error","filePath":"optimizerDuck/Domain/Revert/Steps/ScheduledTaskRevertStep.cs","lineNumber":84,"sourceCode":"    public JObject ToData()\n    {\n        return new JObject\n        {\n            [nameof(FullPath)] = FullPath,\n            [nameof(OriginalEnabled)] = OriginalEnabled,\n        };\n    }\n\n    /// <summary>\n    ///     Deserializes a <see cref=\"ScheduledTaskRevertStep\" /> from JSON data.\n    /// </summary>\n    /// <param name=\"data\">The JSON data to deserialize.</param>\n    /// <returns>A new <see cref=\"ScheduledTaskRevertStep\" /> instance.</returns>\n    public static ScheduledTaskRevertStep FromData(JObject data)\n    {\n        var enabledToken = data[nameof(OriginalEnabled)];\n        if (enabledToken == null || enabledToken.Type == JTokenType.Null)\n            throw new StepExecutionException(\n                $\"Missing required '{nameof(OriginalEnabled)}' in scheduled-task revert data.\",\n                data.ToString()\n            );\n        return new ScheduledTaskRevertStep\n        {\n            FullPath = data[nameof(FullPath)]?.ToString() ?? string.Empty,\n            OriginalEnabled = enabledToken.Value<bool>(),\n        };\n    }\n}\n","sourceCodeStart":66,"sourceCodeEnd":95,"githubUrl":"https://github.com/itsfatduck/optimizerDuck/blob/36acf585ae122a09f0e29eb4acedfaf94e81c0de/optimizerDuck/Domain/Revert/Steps/ScheduledTaskRevertStep.cs#L66-L95","documentation":"ScheduledTaskRevertStep.FromData throws this during deserialization when the persisted revert JSON lacks the OriginalEnabled field. The revert system is fail-closed: without knowing the original enabled state there is no safe way to undo, so it refuses to construct the step.","triggerScenarios":"Loading a revert file whose JSON was hand-edited, truncated, produced by an older app version that did not persist OriginalEnabled, or corrupted mid-write (though atomic writes make this unlikely). data[\"OriginalEnabled\"] is null or JTokenType.Null.","commonSituations":"Manually editing %LocalAppData%\\optimizerDuck\\Revert\\{id}.json and dropping the field; migrating revert data between app versions; a bug in an older build writing incomplete step data.","solutions":["Re-apply the optimization so a fresh, complete revert file is written, then revert again.","If the original state is known, edit the revert JSON to add \"OriginalEnabled\": true|false and retry.","If the state is unknowable, delete the revert file %LocalAppData%\\optimizerDuck\\Revert\\{id}.json (accepting the task stays in its current state).","Restore the file from backup before editing."],"exampleFix":"// before (revert JSON)\n{ \"Steps\": [ { \"$type\": \"ScheduledTaskRevertStep\", \"FullPath\": \"\\\\X\\\\Y\" } ] }\n// after\n{ \"Steps\": [ { \"$type\": \"ScheduledTaskRevertStep\", \"FullPath\": \"\\\\X\\\\Y\", \"OriginalEnabled\": true } ] }","handlingStrategy":"validation","validationCode":"var json = File.ReadAllText(revertFile);\nvar data = JObject.Parse(json);\nbool ok = data[\"Steps\"]?.Any(s => s[\"OriginalEnabled\"] != null) == true;","typeGuard":"static bool HasOriginalEnabled(JObject d) =>\n    d[nameof(ScheduledTaskRevertStep.OriginalEnabled)] is { Type: not JTokenType.Null };","tryCatchPattern":"try { var step = ScheduledTaskRevertStep.FromData(data); }\ncatch (StepExecutionException ex) when (ex.Message.Contains(\"OriginalEnabled\"))\n{ logger.LogError(\"Revert data incomplete; re-apply the optimization to regenerate it\"); }","preventionTips":["Never hand-edit revert JSON; regenerate by re-applying","Back up %LocalAppData%\\optimizerDuck\\Revert before upgrades","Do not migrate revert files across app versions","Rely on atomic writes; never truncate the file manually"],"tags":["csharp","json","revert","deserialization"],"backgroundTag":"missing-required-argument","analyzedSha":"36acf585ae122a09f0e29eb4acedfaf94e81c0de","analyzedAt":"2026-09-13T08:30:13.845Z","contentChangedAt":"2026-09-13T08:30:13.845Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}