stride3d/stride · error · InvalidOperationException

Can't resolve thisType base type for

Error message

Can't resolve thisType base type for {thisType}

What it means

The expander tried to derive a parameter's base type from the intrinsic's thisType (the object a member-style intrinsic is called on), but the thisType's kind has no defined element/base type mapping in the switch. Only texture, buffer and structured-buffer style types are supported there.

Solutions

  1. Call the intrinsic only on supported thisTypes (Texture*, Buffer/StructuredBuffer, Append/ConsumeStructuredBuffer)
  2. If you own the intrinsic declaration, restrict it (e.g. with a type constraint) so it cannot bind to unsupported thisTypes
  3. Extend the switch in IntrinsicTemplateExpander if a new buffer-like type must be supported upstream

Example fix

// before
uint len = myArray.GetLength(); // myArray is float[]
// after
uint len = myStructuredBuffer.GetLength(); // StructuredBuffer<float>
Defensive patterns

Strategy: type-guard

Validate before calling

// Ensure the receiver type has a derivable element/base type before calling buffer/texture intrinsics
if (value is not TextureType and not BufferType and not StructuredBufferType and not AppendStructuredBufferType and not ConsumeStructuredBufferType)
    throw new InvalidOperationException($"{value} has no base type for this intrinsic");

Type guard

bool HasBaseType(TypeBase t) => t is TextureType or BufferType or StructuredBufferType or AppendStructuredBufferType or ConsumeStructuredBufferType;

Try / catch

try { Expand(intrinsic, thisType); }
catch (InvalidOperationException ex) when (ex.Message.StartsWith("Can't resolve thisType base type")) { /* report call-site type mismatch */ }

Prevention

When it happens

Trigger: An intrinsic template whose parameter match index is -1 (match thisType's base type) is invoked with a thisType that is a scalar, vector, matrix, or other type without an element type.

Common situations: Calling a buffer/texture-only intrinsic on a plain scalar or vector variable; SDSL files where an intrinsic meant for StructuredBuffer is applied to arrays.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs:232

                        if (parameterTypeHelper[index].BaseType == null)
                        {
                            // Note: we also check match index doesn't point back to us
                            if (parameterType.Match == null || parameterType.Match.Value.BaseType == index)
                                throw new InvalidOperationException($"Intrinsic {name}: Can't resolve parameter {index} of type {parameterType}");

                            var matchBaseTypeIndex = parameterType.Match.Value.BaseType;
                            if (matchBaseTypeIndex == -1)
                            {
                                // Match thisType's base type
                                parameterTypeHelper[index].BaseType = thisType switch
                                {
                                    TextureType t => t.ReturnType.GetElementType(),
                                    BufferType b => b.BaseType.GetElementType(),
                                    AppendStructuredBufferType b => b.BaseType,
                                    ConsumeStructuredBufferType b => b.BaseType,
                                    StructuredBufferType b => b.BaseType,
                                    null => throw new ArgumentNullException(nameof(thisType)),
                                    _ => throw new InvalidOperationException($"Can't resolve thisType base type for {thisType}"),
                                };
                            }
                            else if (matchBaseTypeIndex == -3)
                            {
                                // Match funcT base type
                                parameterTypeHelper[index].BaseType = thisType switch
                                {
                                    ByteAddressBufferType => ScalarType.UInt,
                                    null => throw new ArgumentNullException(nameof(thisType)),
                                    _ => throw new NotImplementedException($"$funcT not supported for {thisType}"),
                                };
                            }
                            else
                            {
                                parameterTypeHelper[index].BaseType = parameterTypeHelper[matchBaseTypeIndex].BaseType;
                            }
                        }
                    }

View on GitHub (pinned to 96fad776d2)