dotnet/machinelearning · error · NotSupportedException

Type not supported in data loading.

Error message

Type {typeof(T)} not supported in data loading.

What it means

LoadNumberArrayFromStream restricts its generic type parameter T to a fixed set of numeric types (_validTypes) because it uses Buffer.BlockCopy over raw bytes; it throws NotSupportedException when T is any other type. Unsupported types cannot be safely blitted from the byte buffer.

Solutions

  1. Call with a supported numeric type — typically float or int (the types used by the model weights): LoadNumberArrayFromStream<float>(stream, n, sizeof(float)).
  2. Match tSize to the chosen type's byte width (4 for float/int, 8 for long/double where supported).
  3. Check _validTypes / the documented type list before choosing T; convert data after loading a supported type if needed.
  4. Wrap in try-catch on NotSupportedException to report the unsupported type argument.

Example fix

// before
var data = FileUtils.LoadNumberArrayFromStream<decimal>(stream, n, 16); // throws

// after
var data = FileUtils.LoadNumberArrayFromStream<float>(stream, n, 4); // supported
Defensive patterns

Strategy: validation

Validate before calling

var supported = new[] { typeof(float), typeof(int) /* + other _validTypes */ };
if (!supported.Contains(typeof(T)))
    throw new NotSupportedException($"Type {typeof(T)} not supported for stream loading.");

Try / catch

try { var data = FileUtils.LoadNumberArrayFromStream<T>(stream, n, tSize); }
catch (NotSupportedException ex) { log.LogError(ex, "Unsupported element type {Type}", typeof(T)); throw; }

Prevention

When it happens

Trigger: Calling LoadNumberArrayFromStream<T> with T outside the supported numeric set — e.g., LoadNumberArrayFromStream<decimal>, LoadNumberArrayFromStream<string>, LoadNumberArrayFromStream<double> if double is not in _validTypes — while loading tensor/model data.

Common situations: Trying to deserialize a checkpoint stored in one precision (float) into another type parameter, or generically calling with an unconstrained T inferred from a generic helper.

Related errors


AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11). Data as JSON: /api/errors/1506203a069a0151. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.ML.TorchSharp/Utils/FileUtils.cs:50

        /// Load a continuous segment of bytes from stream and parse them into a number array.
        /// NOTE: this function is only for little-endian storage!
        /// </summary>
        /// <typeparam name="T">should be a numeric type</typeparam>
        /// <param name="stream">the stream to read from its current position</param>
        /// <param name="numElements">expected number of parsed numbers</param>
        /// <param name="tSize">number of bytes occupied by the specified type</param>
        /// <exception cref="NotSupportedException">When the generic type T is not a valid numeric type.</exception>
        /// <exception cref="ArgumentException"/>
        /// <exception cref="InvalidDataException">When the contents in the stream don't match the need.</exception>
        public static IEnumerable<T> LoadNumberArrayFromStream<T>(Stream stream, int numElements, int tSize)
        {
            if (stream == null || !stream.CanRead)
            {
                throw new ArgumentException($"Stream should be non-null and its stream.CanRead property should be true.");
            }
            if (!_validTypes.Contains(typeof(T)))
            {
                throw new NotSupportedException($"Type {typeof(T)} not supported in data loading.");
            }

            var numBytesConsumed = numElements * tSize;
            var byteBuffer = new byte[numBytesConsumed];
            var numBytesRead = stream.Read(byteBuffer, 0, numBytesConsumed);
            if (numBytesConsumed != numBytesRead)
            {
                throw new InvalidDataException(
                    $"The number of bytes read from stream is less than expected. Please check the data files.");
            }

            var targetBuffer = new T[numBytesConsumed / tSize];
            Buffer.BlockCopy(byteBuffer, 0, targetBuffer, 0, numBytesConsumed);
            return targetBuffer;
        }
    }
}

View on GitHub (pinned to 7b76e69cf9)