LuckyPennySoftware/AutoMapper · error · InvalidOperationException
Context.Items are only available when using a Map overload t
Error message
Context.Items are only available when using a Map overload that takes Action<IMappingOperationOptions>! Consider using Context.TryGetItems instead.
What it means
ResolutionContext.Items is only backed by storage when the top-level Map call passed an Action<IMappingOperationOptions> (where items are set). In a default/empty context (e.g. a nested call or a resolver invoked from a Map overload without options), accessing Items calls CheckDefault which throws InvalidOperationException and suggests TryGetItems. The library deliberately refuses to silently hand back an unavailable dictionary.
Source
Thrown at src/AutoMapper/ResolutionContext.cs:110
internal static void CheckContext(ref ResolutionContext resolutionContext)
{
if (resolutionContext.IsDefault)
{
resolutionContext = new(resolutionContext._mapper);
}
}
internal TDestination MapInternal<TSource, TDestination>(TSource source, TDestination destination, MemberMap memberMap) =>
_mapper.Map(source, destination, this, memberMap: memberMap);
internal object Map(object source, object destination, Type sourceType, Type destinationType, MemberMap memberMap) =>
_mapper.Map(source, destination, this, sourceType, destinationType, memberMap);
private void CheckDefault()
{
if (IsDefault)
{
ThrowInvalidMap();
}
}
private static void ThrowInvalidMap() => throw new InvalidOperationException("Context.Items are only available when using a Map overload that takes Action<IMappingOperationOptions>! Consider using Context.TryGetItems instead.");
}
public readonly record struct ContextCacheKey(object Source, Type DestinationType)
{
public override int GetHashCode() => HashCode.Combine(DestinationType, RuntimeHelpers.GetHashCode(Source));
public bool Equals(ContextCacheKey other) => DestinationType == other.DestinationType && Source == other.Source;
}View on GitHub (pinned to dfa6dd587c)
Solutions
- Replace context.Items with context.TryGetItems(out var items) and handle the null/items-missing case gracefully.
- At call sites that need items, use mapper.Map<S,D>(src, opts => opts.Items["key"] = value) so a non-default context is in effect.
- Make item consumption optional and fall back to a sensible default when items are absent.
- Audit every resolver/converter to ensure none assume Items is always populated.
Example fix
// before
public int Resolve(Source s, Dest d, int dest, ResolutionContext ctx) => (int)ctx.Items["factor"];
var dto = mapper.Map<Dest>(src); // throws: Items unavailable
// after
public int Resolve(Source s, Dest d, int dest, ResolutionContext ctx) =>
ctx.TryGetItems(out var items) && items.TryGetValue("factor", out var f) ? (int)f : 1;
var dto = mapper.Map<Dest>(src); Defensive patterns
Strategy: validation
Validate before calling
// Always probe with TryGetItems before touching Items:
if (context.TryGetItems(out var items) && items.TryGetValue("factor", out var f))
{
factor = (int)f;
}
else
{
factor = 1; // safe default when no options callback was supplied
} Prevention
- Never read context.Items unconditionally in resolvers/converters; always use TryGetItems.
- At call sites that rely on items, pass the options overload mapper.Map<S,D>(src, opts => opts.Items[k] = v).
- Treat items as optional and define a fallback so missing items degrade gracefully.
When it happens
Trigger: Reading context.Items["key"] from a value resolver, type converter, BeforeMap/AfterMap, or custom mapper when the outer Map used the simple overload mapper.Map<S,D>(src) with no options callback, leaving IsDefault true.
Common situations: A resolver reads Items but some call sites use the parameterless Map overload; a refactor dropped the options callback; unit-testing a resolver in isolation; items that were assumed to always be present.
AI-assisted analysis of LuckyPennySoftware/AutoMapper@dfa6dd587c (2026-08-13).
Data as JSON: /api/errors/333ec571cb90982e.
Report an issue: GitHub.