stride3d/stride · error · InvalidOperationException

Converter is not null but previous Converter was null

Error message

Converter{i} is not null but previous Converter{i - 1} was null

What it means

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.

Solutions

  1. Ensure null converters only appear at the end of the chain
  2. Reorder or remove converters so no gap precedes a non-null one
  3. Fix DI/factory registration so every earlier converter resolves non-null

Example fix

// before
converter2 = new TrimConverter(); converter1 = null; // gap
// after
converter1 = new TrimConverter(); converter2 = new TrimConverter();
Defensive patterns

Strategy: validation

Validate before calling

if (converters.SkipLast(1).Any(c => c == null) && converters.TakeWhile(c => c != null).Count() < Array.FindLastIndex(converters, c => c != null))
    throw new InvalidOperationException("Null converter found in middle of chain");

Type guard

bool HasNoGaps(IValueConverter[] c) => Array.FindLastIndex(c, x => x != null) <= c.TakeWhile(x => x != null).Count();

Try / catch

try { output = chained.Convert(value, targetType, parameter, culture); }
catch (InvalidOperationException ex) { Log.Error("Chained converter misconfigured", ex); output = DependencyProperty.UnsetValue; }

Prevention

When it happens

Trigger: 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.

Common situations: XAML/declaration errors when assembling the chain; refactoring that deletes a step but keeps later ones; DI resolution returning null for an intermediate converter.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/0d22b698a61ab250. Report an issue: GitHub.

Appendix: source

Thrown at sources/presentation/Stride.Core.Presentation.Wpf/ValueConverters/Chained.cs:265

        }

        /// <inheritdoc/>
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var output = value;
            var conversionEnded = false;

            for (var i = 0; i < MaxConverterCount; ++i)
            {
                var input = output;
                if (converters[i] == null)
                {
                    conversionEnded = true;
                    continue;
                }

                if (conversionEnded)
                    throw new InvalidOperationException($"Converter{i} is not null but previous Converter{i - 1} was null");

                var type = converterTargetType[i] ?? ((i == MaxConverterCount - 1) || converters[i + 1] == null ? targetType : typeof(object));
                output = converters[i].Convert(input, type, converterParameters[i], culture);
            }
            return output;
        }

        /// <inheritdoc/>
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var output = value;

            var conversionStarted = false;

            for (var i = MaxConverterCount - 1; i >= 0; --i)
            {
                var input = output;
                if (converters[i] == null)

View on GitHub (pinned to 96fad776d2)