dotnet/machinelearning · error · NotSupportedException
Strings.ImmutableColumn
Error message
Strings.ImmutableColumn
What it means
ArrowStringDataFrameColumn is immutable: the protected SetValue override always throws NotSupportedException(Strings.ImmutableColumn). Any API that mutates a single value by row index (the base-class indexer setter, FillWith value assignment paths) hits this throw. The column only supports append-style construction and reads.
Source
Thrown at src/Microsoft.Data.Analysis/DataFrameColumns/ArrowStringDataFrameColumn.cs:278
{
fixed (byte* data = &MemoryMarshal.GetReference(bytes))
return Encoding.UTF8.GetString(data, bytes.Length);
}
}
/// <inheritdoc/>
protected override IReadOnlyList<object> GetValues(long startIndex, int length)
{
var ret = new List<object>();
while (ret.Count < length)
{
ret.Add(GetValueImplementation(startIndex++));
}
return ret;
}
/// <inheritdoc/>
protected override void SetValue(long rowIndex, object value) => throw new NotSupportedException(Strings.ImmutableColumn);
/// <summary>
/// Indexer to get values. This is an immutable column
/// </summary>
/// <param name="rowIndex">Zero based row index</param>
/// <returns>The value stored at this <paramref name="rowIndex"/></returns>
public new string this[long rowIndex]
{
get => GetValueImplementation(rowIndex);
set => throw new NotSupportedException(Strings.ImmutableColumn);
}
/// <summary>
/// Returns <paramref name="length"/> number of values starting from <paramref name="startIndex"/>.
/// </summary>
/// <param name="startIndex">The index of the first value to return.</param>
/// <param name="length">The number of values to return starting from <paramref name="startIndex"/></param>View on GitHub (pinned to 7b76e69cf9)
Solutions
- Do not mutate in place: build a new column with modified values and replace it in the collection.
- Use a regular StringDataFrameColumn (or PrimitiveDataFrameColumn) when in-place edits are required.
- Route writes through Append (on a fresh column) rather than SetValue-based APIs.
- Wrap mutation logic in a check: if (col is ArrowStringDataFrameColumn) clone-and-replace, else mutate.
Example fix
// before
((DataFrameColumn)df.Columns["s"])[5] = "new"; // NotSupportedException
// after
var values = Enumerable.Range(0, (int)df.Columns["s"].Length)
.Select(i => i == 5 ? "new" : df.Columns["s"][i].ToString());
df["s"] = new StringDataFrameColumn("s", values); Defensive patterns
Strategy: type-guard
Validate before calling
if (df.Columns[name] is ArrowStringDataFrameColumn)
throw new InvalidOperationException("Column is immutable; replace instead of mutating"); Type guard
static bool IsMutableColumn(DataFrameColumn c) => c is not ArrowStringDataFrameColumn;
Try / catch
try { baseCol[rowIndex] = value; }
catch (NotSupportedException) { /* rebuild column with updated value and reassign */ } Prevention
- Treat Arrow-backed columns as read-only
- Use StringDataFrameColumn for editable string data
- Centralize mutation behind a helper that clones-and-replaces
- Check column type before in-place edits
When it happens
Trigger: Assigning through the base DataFrameColumn indexer ((DataFrameColumn)col)[rowIndex] = value, calling base-class APIs that call SetValue (e.g. certain Fill/apply implementations), or any mutation helper built on SetValue.
Common situations: Treating an Arrow-backed column (loaded from Arrow IPC/Feather) like a regular editable PrimitiveDataFrameColumn; generic code written against DataFrameColumn that mutates in place.
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
- null
- TKey
- MismatchedColumnLengths
- Parameter must not be null, empty, or whitespace
- Value cannot be null. (Parameter 'idColumns')
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/2c24ac52790bfaa3.
Report an issue: GitHub.