dotnet/machinelearning · error · InvalidOperationException
Not a RowToRowMapper.
Error message
Not a RowToRowMapper.
What it means
SequentialTransformerBase (used by time-series transforms like SSA and anomaly detectors) is a stateful, schema-dependent transformer: its output depends on accumulated input history, not just per-row math. Therefore it cannot provide an IRowToRowMapper, and GetRowToRowMapper always throws this InvalidOperationException. Callers that require a composable row-to-row mapper (e.g. certain pipeline internals) cannot use this transformer directly.
Source
Thrown at src/Microsoft.ML.TimeSeries/SequentialTransformerBase.cs:454
var bs = new BinarySaver(Host, new BinarySaver.Arguments());
bs.TryWriteTypeDescription(ctx.Writer.BaseStream, OutputColumnType, out int byteWritten);
}
public abstract DataViewSchema GetOutputSchema(DataViewSchema inputSchema);
internal abstract IStatefulRowMapper MakeRowMapper(DataViewSchema schema);
internal SequentialDataTransform MakeDataTransform(IDataView input)
{
Host.CheckValue(input, nameof(input));
return new SequentialDataTransform(Host, this, input, MakeRowMapper(input.Schema));
}
public IDataView Transform(IDataView input) => MakeDataTransform(input);
public IRowToRowMapper GetRowToRowMapper(DataViewSchema inputSchema)
{
throw new InvalidOperationException("Not a RowToRowMapper.");
}
IRowToRowMapper IStatefulTransformer.GetStatefulRowToRowMapper(DataViewSchema inputSchema)
{
Host.CheckValue(inputSchema, nameof(inputSchema));
return new TimeSeriesRowToRowMapperTransform(Host, new EmptyDataView(Host, inputSchema), MakeRowMapper(inputSchema));
}
internal virtual IStatefulTransformer Clone() => (SequentialTransformerBase<TInput, TOutput, TState>)MemberwiseClone();
IStatefulTransformer IStatefulTransformer.Clone() => Clone();
internal sealed class SequentialDataTransform : TransformBase, ITransformTemplate, IRowToRowMapper
{
private readonly IStatefulRowMapper _mapper;
private readonly SequentialTransformerBase<TInput, TOutput, TState> _parent;
private readonly IDataView _transform;
private readonly ColumnBindings _bindings;View on GitHub (pinned to 7b76e69cf9)
Solutions
- Do not call GetRowToRowMapper on time-series transformers; instead call Transform(input) to get an IDataView of the transformed data.
- If a stateful row-to-row mapper is needed, use IStatefulTransformer.GetStatefulRowToRowMapper (implemented here via TimeSeriesRowToRowMapperTransform) instead.
- Restructure the pipeline so the time-series stage is a terminal/forecasting step, and only row-to-row-friendly transformers are exposed to mapper-based code paths.
- Guard with a type check (transformer is IRowToRowMapper) before calling, and fall back to Transform.
Example fix
// before
var mapper = transformer.GetRowToRowMapper(schema); // throws
// after
if (transformer is IRowToRowMapper mapper2)
{
var m = mapper2;
}
else
{
var output = transformer.Transform(dataView); // stateful path
} Defensive patterns
Strategy: try-catch
Validate before calling
bool safe = transformer is not IRowToRowMapper && transformer is IStatefulTransformer;
Type guard
static bool HasRowToRowMapper(ITransformer t) => t is IRowToRowMapper;
Try / catch
try { var mapper = transformer.GetRowToRowMapper(schema); }
catch (InvalidOperationException ex) when (ex.Message == "Not a RowToRowMapper.")
{ var output = transformer.Transform(dataView); } Prevention
- Check transformer capabilities via `is IRowToRowMapper` before mapper-based code paths.
- Treat time-series transformers as stateful/terminal pipeline stages.
- Use IStatefulTransformer.GetStatefulRowToRowMapper for stateful mappers.
When it happens
Trigger: Calling GetRowToRowMapper(inputSchema) on any Microsoft.ML.TimeSeries transformer deriving from SequentialTransformerBase (e.g. SsaForecasting, SrCnnEntireAnomalyDetector) or on an EstimatorChain/transform that internally contains one, typically via ITransformer.GetRowToRowMapper or ML.NET's 'transform as mapper' code paths.
Common situations: Tooling that generically calls GetRowToRowMapper to inspect or cache per-row transforms; pipelines that try to prune/compose mappers over a time-series forecasting model; code written for row-to-row transformers being reused with time-series transformers.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Not finite unit value
- MismatchedColumnLengths
- Parameter must not be null, empty, or whitespace
- Value cannot be null. (Parameter 'idColumns')
- Must provide at least 1 ID column
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/a17aea9d6f8c02f6.
Report an issue: GitHub.