abpframework/abp · error · AbpException
Options must be derived from the {typeof(AbpDynamicOptionsMa
Error message
Options must be derived from the {typeof(AbpDynamicOptionsManager<>).FullName}! What it means
Thrown by OptionsAbpDynamicOptionsManagerExtensions.ToDynamicOptions when SetAsync is called on an IOptions<T> instance that is not an AbpDynamicOptionsManager<T>. ABP's dynamic-configuration feature overrides the default OptionsManager so option values can be refreshed at runtime; calling SetAsync on a plain/externally-supplied IOptions has no dynamic backing store to update.
Source
Thrown at framework/src/Volo.Abp.Core/Microsoft/Extensions/Options/OptionsAbpDynamicOptionsManagerExtensions.cs:29
{
return options.ToDynamicOptions().SetAsync();
}
public static Task SetAsync<T>(this IOptions<T> options, string name)
where T : class
{
return options.ToDynamicOptions().SetAsync(name);
}
private static AbpDynamicOptionsManager<T> ToDynamicOptions<T>(this IOptions<T> options)
where T : class
{
if (options is AbpDynamicOptionsManager<T> dynamicOptionsManager)
{
return dynamicOptionsManager;
}
throw new AbpException($"Options must be derived from the {typeof(AbpDynamicOptionsManager<>).FullName}!");
}
}
View on GitHub (pinned to 7ed43b1931)
Solutions
- Ensure the AbpOptions module / dynamic-configuration infrastructure is loaded so IOptions<T> resolves as AbpDynamicOptionsManager<T> at runtime.
- In tests, do not call SetAsync on Options.Create; instead register dynamic options or skip the SetAsync call.
- If you only need static options, read .Value instead of calling SetAsync.
- Confirm AbpDynamicOptionsManager is the registered IOptions<T> implementation (check that AddAbp/your module wired IOptions via the ABP options services).
Example fix
// before — Options.Create is not dynamic
var opts = Options.Create(new MyOptions { X = 1 });
await opts.SetAsync(); // throws
// after — register through ABP dynamic options, or just read the value
var value = opts.Value;
// or configure dynamic options via Configure<T>/ ABP's SetConfigurationValue path Defensive patterns
Strategy: type-guard
Validate before calling
// Only call SetAsync when the resolved options are ABP's dynamic manager
if (options is Volo.Abp.Options.AbpDynamicOptionsManager<T> dynamicOpts)
await dynamicOpts.SetAsync();
else
throw new InvalidOperationException("IOptions<T> is not the ABP dynamic manager; cannot SetAsync."); Type guard
static bool IsDynamic<T>(IOptions<T> options) where T : class =>
options is Volo.Abp.Options.AbpDynamicOptionsManager<T>; Prevention
- Ensure the ABP options/dynamic-configuration module is loaded so IOptions<T> resolves as AbpDynamicOptionsManager<T>.
- In tests, avoid SetAsync on Options.Create; read .Value instead.
- Type-check before calling SetAsync when the source of IOptions<T> is uncertain.
When it happens
Trigger: Invoking options.SetAsync() / options.SetAsync(name) where options is a standard OptionsManager<T>, a wrapped IOptions<T> from a non-ABP source, or a test double — anything that is not AbpDynamicOptionsManager<T>.
Common situations: Unit tests injecting a plain IOptions<T> (e.g. Options.Create(value)) and then calling SetAsync; code that resolves IOptions<T> from a container not configured with ABP's dynamic options; using Microsoft.Extensions.Options directly without the ABP options module.
Related errors
- Could not find singleton service: {typeof(T).AssemblyQualifi
- Could not find {typeof(IServiceProviderFactory<TContainerBui
- Could not find an implementation of {typeof(IConfiguration).
- An object accessor is registered before for type: {typeof(T)
- Could not find an object of {typeof(T).AssemblyQualifiedName
AI-assisted analysis of abpframework/abp@7ed43b1931 (2026-08-13).
Data as JSON: /api/errors/6ac5b23870a6c1db.
Report an issue: GitHub.