{"record":{"id":"a72950ae991983aa","repo":"stride3d/stride","slug":"converter-i-is-null-but-following-converter-i-1-is-not-null-a72950","errorCode":null,"errorMessage":"Converter{i} is null but following Converter{i + 1} is not null","messagePattern":"Converter(.+?) is null but following Converter(.+?) is not null","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Presentation.Wpf/ValueConverters/Chained.cs","lineNumber":287,"sourceCode":"            }\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)\n                {\n                    if (!conversionStarted)\n                        continue;\n                    throw new InvalidOperationException($\"Converter{i} is null but following Converter{i + 1} is not null\");\n                }\n\n                conversionStarted = true;\n\n                var type = converterTargetType[i] ?? (i == 0 ? targetType : typeof(object));\n                output = converters[i].ConvertBack(input, type, converterParameters[i], culture);\n            }\n            return output;\n        }\n    }\n}\n","sourceCodeStart":269,"sourceCodeEnd":299,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Presentation.Wpf/ValueConverters/Chained.cs#L269-L299","documentation":"Chained.ConvertBack throws this InvalidOperationException when a converter is null after the back-conversion has already started, meaning a null appears in the middle of the chain while later converters still exist. Back-conversion can skip leading nulls but not gaps.","triggerScenarios":"A ChainedConverter whose Converter0 is null but Converter1 is set, hit during ConvertBack after conversion started; runtime mutation leaving a null in the middle of the chain.","commonSituations":"Two-way bindings (default binding mode) exercising ConvertBack on a chain configured only for forward use; mis-ordered converter declarations in XAML; a converter step disposed and set to null at runtime.","solutions":["Ensure no null converter appears before a non-null one in the chain","Set the binding to OneWay when the chain does not support ConvertBack","Fix converter ordering so leading entries are non-null"],"exampleFix":"// before\nconverter0 = null; converter1 = new TrimConverter(); // gap hit in ConvertBack\n// after\nconverter0 = new TrimConverter(); converter1 = new TrimConverter();","handlingStrategy":"validation","validationCode":"if (converters.Any(c => c == null) && converters.TakeWhile(c => c != null).Count() < Array.FindLastIndex(converters, c => c != null))\n    throw new InvalidOperationException(\"Gap in converter chain for ConvertBack\");","typeGuard":"bool IsValidForConvertBack(IValueConverter[] c) => c.Length == 0 || Array.TrueForAll(c.Take(Array.FindLastIndex(c, x => x != null) + 1).ToArray(), x => x != null);","tryCatchPattern":"try { output = chained.ConvertBack(value, targetType, parameter, culture); }\ncatch (InvalidOperationException ex) { Log.Error(\"ConvertBack chain gap\", ex); return Binding.DoNothing; }","preventionTips":["Use OneWay bindings for chains lacking full back-conversion support","Keep converter arrays dense (no nulls before a non-null entry)","Assert chain validity in unit tests for both directions","Avoid nulling converters at runtime; rebuild the chain instead"],"tags":["wpf","value-converter","chained-converter","twoway-binding"],"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"}