LuckyPennySoftware/AutoMapper · error · InvalidOperationException
Not enough room in destination array {destination}
Error message
Not enough room in destination array {destination} What it means
Maps a flat source collection into a multidimensional (ranked) destination array via MultidimensionalArrayFiller, filling cells dimension by dimension. The throw fires when the dimension counter walks past every dimension (dimension < 0) while NewValue still has elements to place, i.e. the source holds more values than the destination array's total cell capacity. It is the library's way of refusing a silent truncation when shapes do not match.
Source
Thrown at src/AutoMapper/Mappers/CollectionMapper.cs:260
bool MustMap(Type sourceType, Type destinationType) => !destinationType.IsAssignableFrom(sourceType) ||
configuration.FindTypeMapFor(sourceType, destinationType) != null;
}
}
}
public readonly struct MultidimensionalArrayFiller(Array destination)
{
readonly int[] _indices = new int[destination.Rank];
public void NewValue(object value)
{
var dimension = destination.Rank - 1;
var changedDimension = false;
while (_indices[dimension] == destination.GetLength(dimension))
{
_indices[dimension] = 0;
dimension--;
if (dimension < 0)
{
throw new InvalidOperationException("Not enough room in destination array " + destination);
}
_indices[dimension]++;
changedDimension = true;
}
destination.SetValue(value, _indices);
if (changedDimension)
{
_indices[dimension + 1]++;
}
else
{
_indices[dimension]++;
}
}
}View on GitHub (pinned to dfa6dd587c)
Solutions
- Size the destination multidimensional array so the product of all GetLength(d) is >= source element count before mapping.
- Trim or page the source collection so its count fits the fixed destination shape.
- Switch the destination to a 1D array or List<T> when the multidimensional shape is not actually required.
- Pre-validate dimensions against the source and surface a domain error instead of letting AutoMapper throw.
Example fix
// before var dest = new int[2, 2]; mapper.Map(srcList, dest); // throws if srcList.Count > 4 // after var rows = (int)Math.Ceiling(Math.Sqrt(srcList.Count)); var dest = new int[rows, srcList.Count % rows == 0 ? srcList.Count / rows : srcList.Count / rows + 1]; mapper.Map(srcList, dest);
Defensive patterns
Strategy: validation
Validate before calling
static long ArrayCapacity(Array a)
{
long capacity = 1;
for (int d = 0; d < a.Rank; d++) capacity *= a.GetLength(d);
return capacity;
}
long needed = source.Cast<object>().LongCount();
if (needed > ArrayCapacity(destination))
throw new ArgumentException($"Destination array capacity ({ArrayCapacity(destination)}) < source count ({needed}).");
mapper.Map(source, destination); Try / catch
try { mapper.Map(source, destination); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Not enough room in destination array"))
{
// recompute destination dimensions or trim the source, then retry once
} Prevention
- Always derive multidimensional destination lengths from the source count, not from hardcoded constants.
- Prefer List<T> or a 1D array when the multidimensional shape is not a hard requirement.
- Add a unit test that maps the largest expected source and asserts no throw.
When it happens
Trigger: Calling Map from an IEnumerable/array onto a System.Array with Rank > 1 (e.g. int[,], string[,,]) where source.Count() exceeds the product of destination.GetLength(d) over all d. Each source element invokes MultidimensionalArrayFiller.NewValue, so one extra element after the last cell is full triggers the throw.
Common situations: Destination array allocated with stale/wrong dimension lengths after the source grew; off-by-one when sizing dims at runtime; data import where row/column counts exceed the pre-allocated matrix; reusing a fixed-size buffer for variable-size input.
AI-assisted analysis of LuckyPennySoftware/AutoMapper@dfa6dd587c (2026-08-13).
Data as JSON: /api/errors/257c602e4ab0cc84.
Report an issue: GitHub.