ScopeNotInitializedError¶
Symptom¶
resolve() or resolve_provider() raises it when a provider's scope is deeper than the container
that has to build it. Resolving a REQUEST-scoped provider from the APP container prints:
modern_di.exceptions.container.ScopeNotInitializedError: Cannot resolve dependency chain:
REQUEST Session (myapp.providers:7)
caused by: Provider of scope REQUEST cannot be resolved in container of scope APP.
See: https://modern-di.modern-python.org/troubleshooting/scope-not-initialized-error/
When a shallower provider depends on the deeper one, the chain starts at the shallower provider:
modern_di.exceptions.container.ScopeNotInitializedError: Cannot resolve dependency chain:
APP UserCache (myapp.providers:10)
REQUEST └─> Session (myapp.providers:7)
caused by: Provider of scope REQUEST cannot be resolved in container of scope APP.
See: https://modern-di.modern-python.org/troubleshooting/scope-not-initialized-error/
Each chain line names a provider's scope and type and, when it can be found, the module:line where
its creator is defined (the class or function, not the Factory(...) line). .provider_scope and
.container_scope hold the two scopes in the caused by line.
Cause¶
The container that has to build the provider is shallower than the provider's scope, in one of two ways:
- You resolved a provider from a container shallower than the provider's scope, and no container at
that scope exists below it yet. The first sample is
container.resolve(Session)on theAPPcontainer, with noREQUESTchild built. - A provider depends on a deeper-scoped one, a captive dependency. An
APP-scopedUserCacheis built in theAPPcontainer even when you callresolve(UserCache)on aREQUESTchild, and theAPPcontainer cannot build theREQUEST-scopedSessionit needs. That is why the second sample names container scopeAPPalthough the call went to aREQUESTcontainer.
Fix¶
In the first case, build the deeper container and resolve from it:
# Works
request_container = app_container.build_child_container(scope=Scope.REQUEST)
request_container.resolve(Session)
In the captive case a deeper container does not help. Move the depending provider to the deeper
scope, or give the dependency a shallower scope if its lifetime allows. container.validate() finds
every captive dependency at startup and reports it as
InvalidScopeDependencyError, whose page shows both fixes.
See also¶
- InvalidScopeDependencyError — the same problem reported by
validate(). - Scopes: the scope dependency rule — why a provider cannot depend on a deeper scope.
- Captive dependency — the bug this error usually points at.