{"record":{"id":"30d563326a7f0f5d","repo":"stride3d/stride","slug":"can-t-cast-between-array-of-different-sizes-cast-from","errorCode":null,"errorMessage":"Can't cast between array of different sizes (cast from {valueType} to {castType})","messagePattern":"Can't cast between array of different sizes \\(cast from (.+?) to (.+?)\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs","lineNumber":501,"sourceCode":"    public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolType castType)\n    {\n        var valueId = value.Id;\n        var valueType = context.ReverseTypes[value.TypeId];\n        var originalType = valueType;\n\n        // No conversion necessary?\n        if (castType == valueType)\n            return value;\n\n        if (castType is StructType || valueType is StructType)\n            throw new NotImplementedException($\"Can't cast between structures (cast from {valueType} to {castType})\");\n\n        if (castType is ArrayType a1 && valueType is ArrayType a2)\n        {\n            if (a1.BaseType == a2.BaseType)\n            {\n                if (a1.Size != -1 && a1.Size != a2.Size)\n                    throw new InvalidOperationException(($\"Can't cast between array of different sizes (cast from {valueType} to {castType})\"));\n                // Some sizes are undetermined; this can only happen during compilation due to incomplete generics type\n                // TODO: do a \"check pass\" later to make sure this won't happen after generics instantiation?\n                return value;\n            }\n            else\n            {\n                throw new InvalidOperationException(($\"Can't cast between array of different types (cast from {valueType} to {castType})\"));\n            }\n        }\n\n        if (castType is StreamsType { Kind: var targetKind }\n            && valueType is StreamsType { Kind: var sourceKind }\n            // Note: order is Input, Streams, Output\n            && targetKind > sourceKind)\n        {\n            return new(InsertData(new OpCopyLogical(context.GetOrRegister(castType), context.Bound++, value.Id)));\n        }\n","sourceCodeStart":483,"sourceCodeEnd":519,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs#L483-L519","documentation":"When converting between array types with the same base element type, sizes must match; only Size == -1 (undetermined size from incomplete generics) is allowed to pass through unchecked. A definite size mismatch (e.g. float[3] to float[4]) cannot be lowered, so Convert throws InvalidOperationException.","triggerScenarios":"Calling Convert where both types are ArrayType with equal base types but different known sizes (a1.Size != -1 && a1.Size != a2.Size).","commonSituations":"Passing an array of the wrong length to a shader function or parameter; changing an array constant's length without updating its consumer; generics instantiation leaving stale sizes.","solutions":["Make both arrays the same length","Declare the target/parameter size to match the source array (or use the same constant)","Wrap the fixed-size array in a type with matching size before conversion","If the size is genuinely dynamic, model it via generics or a runtime-length construct supported by the compiler"],"exampleFix":"// before\nfloat[4] a = (float[4])float3Array; // different sizes\n// after\nfloat[3] a = (float[3])float3Array; // sizes match","handlingStrategy":"validation","validationCode":"if (valueType is ArrayType a1 && castType is ArrayType a2 && a1.BaseType == a2.BaseType && a1.Size != -1 && a1.Size != a2.Size)\n    throw new InvalidOperationException($\"Array size mismatch {a1.Size} vs {a2.Size}\");","typeGuard":"bool ArraysMatch(ArrayType a, ArrayType b) => a.BaseType == b.BaseType && (a.Size == -1 || b.Size == -1 || a.Size == b.Size);","tryCatchPattern":"try { converted = Builder.Convert(value, castType); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"array of different sizes\"))\n{ /* reject the call or resize the array at source */ }","preventionTips":["Keep array lengths consistent between producers and consumers","Declare parameter sizes to match actual data","Validate sizes after generics instantiation"],"tags":["spirv","shader-compiler","array","casting"],"backgroundTag":"type-mismatch","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}