Troubleshooting
Diagnose the most common type and lifecycle failures.
Read the diagnostic tag __betterEffectMissingService__... or
__betterEffectMissingRuntimeService__.... Add the missing provider to the Layer, merge the
Layers, or use an explicit override for a test.
merge never silently replaces a provider. Use Layer.override(base, replacement) when
replacement is intentional, and ensure same-tag contracts are compatible.
yield* Service and ServiceRuntime.resolve need an active resolver. Run the program through
Runtime.run, or wrap integration code with ServiceRuntime.run(resolver, callback).
Scope.current, yield* Scope, Effect.add and Effect.acquireRelease require an active
Scope. Use a Runtime execution, Scope.run, or Scope.provide with an existing Scope.
Confirm acquisition succeeded, the resource was registered in the current Scope, and the release
callback or disposal protocol is callable. For Effect.add, the object must expose
Symbol.asyncDispose or Symbol.dispose.
Cleanup failures are secondary when the program failed. Configure onCleanupFailure to observe
them. A successful program can surface a cleanup failure because there is no more specific
primary failure.
Layer generators may yield Service tokens only. Use Result.await and Effect.gen for Result
operations in application programs; use Layer.scopedGen for contextual acquisition and
cleanup.
A debugging checklist
- Confirm the Service tag is non-empty and stable.
- Inspect
LayerProvided,LayerRawRequiredandLayerMissingwhen a composition root fails to typecheck. - Verify the program runs inside the intended Runtime.
- Check whether the resource belongs to the root Scope or execution Scope.
- Preserve the primary Result/exception and inspect cleanup diagnostics separately.