{"record":{"id":"cce8776858f8322e","repo":"dotnet/BenchmarkDotNet","slug":"the-current-object-this-is-frozen-create-a-copy","errorCode":null,"errorMessage":"The current object {this} is frozen. Create a copy to modify.","messagePattern":"The current object (.+?) is frozen\\. Create a copy to modify\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/BenchmarkDotNet/Characteristics/CharacteristicObject.cs","lineNumber":60,"sourceCode":"            sharedValues = [];\n        }\n\n        protected CharacteristicObject(string id) : this()\n        {\n            if (id.IsNotBlank())\n            {\n                IdCharacteristic[this] = id;\n            }\n        }\n        #endregion\n\n        #region Assertions\n\n        private void AssertNotFrozen()\n        {\n            if (Frozen)\n            {\n                throw new InvalidOperationException($\"The current object {this} is frozen. Create a copy to modify.\");\n            }\n        }\n\n        private void AssertIsRoot()\n        {\n            if (Owner != null)\n            {\n                throw new InvalidOperationException(\n                    \"The current operation allowed for root nodes only, \" +\n                    $\"but the value {this} is attached to another node, {Owner}.\");\n            }\n        }\n\n        private void AssertIsNonFrozenRoot()\n        {\n            AssertNotFrozen();\n            AssertIsRoot();\n        }","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/dotnet/BenchmarkDotNet/blob/b515068b61ad1c9c9aa938b8ece4af1e7d6d85a3/src/BenchmarkDotNet/Characteristics/CharacteristicObject.cs#L42-L78","documentation":"CharacteristicObject is an immutable-on-freeze tree: once Frozen is true (propagated through the Owner chain), no mutations are permitted. AssertNotFrozen guards every setter, so attempting to change a value on a Job/config that has already been frozen raises this. Freezing happens when a CharacteristicObject is attached as a child of another or when the root is explicitly frozen for use.","triggerScenarios":"Mutating a Job instance after it has been added to a Config and the Config/runner has frozen it, editing the shared DefaultJobInstance or a resolver-provided template, or reusing a benchmark case's Job object to apply another With(...) modification.","commonSituations":"Calling job.WithRuntime(...) on a Job pulled from an already-built Config, sharing a static Job field across runs and modifying it between runs, or programmatically cloning a config and editing the original.","solutions":["Create a copy before modifying: BDN APIs return new unfrozen instances from With*() builder methods, so chain those instead of mutating in place.","Capture the Job before it is added to a Config and only modify that pre-freeze reference.","Never mutate shared/default instances (Job.Default, default configs); derive a new one from them.","If you hold a frozen object you must change, clone it via its copy/build API first."],"exampleFix":"// before - 'job' was already added to a frozen Config\njob.WithRuntime(newRuntime); // throws\n\n// after - builder methods produce a fresh, unfrozen instance\nvar job = originalJob.WithRuntime(newRuntime);","handlingStrategy":"validation","validationCode":"if (job.Frozen)\n    job = job.WithRuntime(newRuntime); // builder returns a fresh unfrozen instance\nelse\n    job.Runtime = newRuntime;","typeGuard":"static bool IsMutable(CharacteristicObject o) => !o.Frozen;","tryCatchPattern":"try { obj.SomeSetter(value); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"frozen\"))\n{\n    var copy = obj.Clone(); // or rebuild via With*\n    copy.SomeSetter(value);\n}","preventionTips":["Treat Job/Config objects as immutable; always use the With*() builder methods that return new instances.","Never mutate shared/default instances (Job.Default) across runs.","Build configs fresh per run rather than reusing a frozen one."],"tags":["characteristics","immutability","frozen","job-config","invalidoperation"],"backgroundTag":null,"analyzedSha":"b515068b61ad1c9c9aa938b8ece4af1e7d6d85a3","analyzedAt":"2026-08-13T19:12:24.196Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}