{"record":{"id":"41c9fff2d4bb22bd","repo":"stride3d/stride","slug":"setobject-can-only-be-used-for-permutation-or-object-keys","errorCode":null,"errorMessage":"SetObject can only be used for Permutation or Object keys","messagePattern":"SetObject can only be used for Permutation or Object keys","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Foundation/Rendering/ParameterCollection.cs","lineNumber":497,"sourceCode":"        {\n            return (T)ObjectValues[parameter.BindingSlot];\n        }\n\n        /// <summary>\n        /// Gets an object.\n        /// </summary>\n        /// <typeparam name=\"T\"></typeparam>\n        /// <param name=\"parameterAccessor\"></param>\n        /// <returns></returns>\n        public T Get<T>(ObjectParameterAccessor<T> parameterAccessor)\n        {\n            return (T)ObjectValues[parameterAccessor.BindingSlot];\n        }\n\n        public void SetObject(ParameterKey key, object value)\n        {\n            if (key.Type != ParameterKeyType.Permutation && key.Type != ParameterKeyType.Object)\n                throw new InvalidOperationException(\"SetObject can only be used for Permutation or Object keys\");\n\n            var accessor = GetObjectParameterHelper(key);\n            if (key.Type == ParameterKeyType.Permutation)\n            {\n                var oldValue = ObjectValues[accessor.Offset];\n                if ((oldValue != null && (value == null || !oldValue.Equals(value))) // oldValue non null => check equality\n                    || (oldValue == null && value != null)) // oldValue null => check if value too\n                        PermutationCounter++;\n            }\n            ObjectValues[accessor.Offset] = value;\n        }\n\n        public object GetObject(ParameterKey key)\n        {\n            if (key.Type != ParameterKeyType.Permutation && key.Type != ParameterKeyType.Object)\n                throw new InvalidOperationException(\"GetObject can only be used for Permutation or Object keys\");\n\n            var accessor = GetObjectParameterHelper(key, false);","sourceCodeStart":479,"sourceCodeEnd":515,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Foundation/Rendering/ParameterCollection.cs#L479-L515","documentation":"SetObject only accepts keys whose ParameterKeyType is Permutation or Object because only those types are backed by the ObjectValues reference array. Calling it with a typed key (e.g. a float or texture key) would corrupt typed storage, so it throws InvalidOperationException.","triggerScenarios":"Calling SetObject with a ParameterKey declared as a value/typed key (key.Type is neither Permutation nor Object).","commonSituations":"Generic helper code that routes all parameter writes through SetObject; refactored key whose type changed; copying parameters between collections with a generic API.","solutions":["Use the typed Set<T> API for the key's actual type","Only call SetObject with keys whose Type is ParameterKeyType.Permutation or ParameterKeyType.Object","Check key.Type before dispatching to SetObject vs Set"],"exampleFix":"// before\ncollection.SetObject(TextureKey, myTexture); // typed key\n// after\ncollection.Set(TextureKey, myTexture);","handlingStrategy":"validation","validationCode":"if (key.Type is not (ParameterKeyType.Permutation or ParameterKeyType.Object))\n    throw new ArgumentException(\"SetObject requires Permutation or Object keys\");\ncollection.SetObject(key, value);","typeGuard":"bool IsObjectKey(ParameterKey key) => key.Type is ParameterKeyType.Permutation or ParameterKeyType.Object;","tryCatchPattern":"try { collection.SetObject(key, value); } catch (InvalidOperationException ex) { /* fall back to typed Set<T> */ }","preventionTips":["Route object/Permutation writes through SetObject and typed writes through Set<T>","Centralize parameter writes in one helper that checks key.Type once"],"tags":["rendering","parameters","invalid-operation"],"backgroundTag":"invalid-argument-value","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}