{"record":{"id":"0d22b698a61ab250","repo":"stride3d/stride","slug":"converter-i-is-not-null-but-previous-converter-i-1-was-null-0d22b6","errorCode":null,"errorMessage":"Converter{i} is not null but previous Converter{i - 1} was null","messagePattern":"Converter(.+?) is not null but previous Converter(.+?) was null","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Presentation.Wpf/ValueConverters/Chained.cs","lineNumber":265,"sourceCode":"        }\n\n        /// <inheritdoc/>\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            var output = value;\n            var conversionEnded = false;\n\n            for (var i = 0; i < MaxConverterCount; ++i)\n            {\n                var input = output;\n                if (converters[i] == null)\n                {\n                    conversionEnded = true;\n                    continue;\n                }\n\n                if (conversionEnded)\n                    throw new InvalidOperationException($\"Converter{i} is not null but previous Converter{i - 1} was null\");\n\n                var type = converterTargetType[i] ?? ((i == MaxConverterCount - 1) || converters[i + 1] == null ? targetType : typeof(object));\n                output = converters[i].Convert(input, type, converterParameters[i], culture);\n            }\n            return output;\n        }\n\n        /// <inheritdoc/>\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            var output = value;\n\n            var conversionStarted = false;\n\n            for (var i = MaxConverterCount - 1; i >= 0; --i)\n            {\n                var input = output;\n                if (converters[i] == null)","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Presentation.Wpf/ValueConverters/Chained.cs#L247-L283","documentation":"Chained.Convert throws this InvalidOperationException when it encounters a non-null converter after a null one earlier in the chain, i.e. converters must be null only as a contiguous suffix ending the chain. A hole in the middle of the chain is an invalid configuration.","triggerScenarios":"Defining a ChainedConverter where Converter1 is null but Converter2 is set; removing a middle converter at runtime leaving a gap; serialization losing a middle converter.","commonSituations":"XAML/declaration errors when assembling the chain; refactoring that deletes a step but keeps later ones; DI resolution returning null for an intermediate converter.","solutions":["Ensure null converters only appear at the end of the chain","Reorder or remove converters so no gap precedes a non-null one","Fix DI/factory registration so every earlier converter resolves non-null"],"exampleFix":"// before\nconverter2 = new TrimConverter(); converter1 = null; // gap\n// after\nconverter1 = new TrimConverter(); converter2 = new TrimConverter();","handlingStrategy":"validation","validationCode":"if (converters.SkipLast(1).Any(c => c == null) && converters.TakeWhile(c => c != null).Count() < Array.FindLastIndex(converters, c => c != null))\n    throw new InvalidOperationException(\"Null converter found in middle of chain\");","typeGuard":"bool HasNoGaps(IValueConverter[] c) => Array.FindLastIndex(c, x => x != null) <= c.TakeWhile(x => x != null).Count();","tryCatchPattern":"try { output = chained.Convert(value, targetType, parameter, culture); }\ncatch (InvalidOperationException ex) { Log.Error(\"Chained converter misconfigured\", ex); output = DependencyProperty.UnsetValue; }","preventionTips":["Only null out converters at the end of the chain","Validate chain completeness at construction time","Ensure DI registration resolves every intermediate converter","Review XAML declarations for removed middle converters"],"tags":["wpf","value-converter","chained-converter","configuration"],"backgroundTag":"invalid-config-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"}