Background
The OTel-resources lifecycle helper (libs/idun_agent_engine/src/idun_agent_engine/observability/otel_lifecycle.py, PR #601) reaches into TWO private OpenTelemetry SDK attributes to fix the silent-drop reload bug (latent bug §3 from idun-dev/tasks/trace-feature-08-05-2026/README.md):
opentelemetry.trace._TRACER_PROVIDER_SET_ONCE is reset to a fresh Once() before each set_tracer_provider(...) call. Required because the SDK's Once gate is the only thing preventing provider swap on reload.
_tracer_provider._active_span_processor._span_processors = () is cleared before provider.shutdown() to prevent double-shutdown of each processor (the helper's per-processor try/log/continue contract is incompatible with MultiSpanProcessor.shutdown's exception propagation).
Both are wrapped in try/except + logger.exception. Engine pyproject.toml pins opentelemetry-api>=1.30,<2.0 and opentelemetry-sdk>=1.30,<2.0 to lock the surface against drift.
Trigger
Open this issue when bumping opentelemetry-sdk to 2.x or any 1.x version where the locked private symbols may have moved.
What to verify
opentelemetry.trace._TRACER_PROVIDER_SET_ONCE still exists and is a Once-like object that can be reset.
TracerProvider._active_span_processor exists and exposes _span_processors as a mutable tuple/list.
tests/integration/observability/test_reload_otel_no_drop.py::test_reload_does_not_log_overriding_warning still passes (this is the integration smoke that confirms the helper successfully prevents the silent-drop bug).
- Helper unit tests in
tests/unit/observability/test_otel_lifecycle.py all pass.
If the symbols have moved
- Check OTel SDK changelog for an officially supported provider-swap API (none exists as of 1.x).
- If a public API has appeared (
unset_tracer_provider, force=True, Reset), migrate to it and remove the private-attr workaround.
- Otherwise, find the renamed symbol and adjust. Bump the version pin to the new range.
References
🤖 Filed during PR #601 wrap-up.
Background
The OTel-resources lifecycle helper (
libs/idun_agent_engine/src/idun_agent_engine/observability/otel_lifecycle.py, PR #601) reaches into TWO private OpenTelemetry SDK attributes to fix the silent-drop reload bug (latent bug §3 fromidun-dev/tasks/trace-feature-08-05-2026/README.md):opentelemetry.trace._TRACER_PROVIDER_SET_ONCEis reset to a freshOnce()before eachset_tracer_provider(...)call. Required because the SDK'sOncegate is the only thing preventing provider swap on reload._tracer_provider._active_span_processor._span_processors = ()is cleared beforeprovider.shutdown()to prevent double-shutdown of each processor (the helper's per-processor try/log/continue contract is incompatible withMultiSpanProcessor.shutdown's exception propagation).Both are wrapped in
try/except + logger.exception. Enginepyproject.tomlpinsopentelemetry-api>=1.30,<2.0andopentelemetry-sdk>=1.30,<2.0to lock the surface against drift.Trigger
Open this issue when bumping
opentelemetry-sdkto 2.x or any 1.x version where the locked private symbols may have moved.What to verify
opentelemetry.trace._TRACER_PROVIDER_SET_ONCEstill exists and is aOnce-like object that can be reset.TracerProvider._active_span_processorexists and exposes_span_processorsas a mutable tuple/list.tests/integration/observability/test_reload_otel_no_drop.py::test_reload_does_not_log_overriding_warningstill passes (this is the integration smoke that confirms the helper successfully prevents the silent-drop bug).tests/unit/observability/test_otel_lifecycle.pyall pass.If the symbols have moved
unset_tracer_provider,force=True,Reset), migrate to it and remove the private-attr workaround.References
idun-dev/tasks/trace-feature-08-05-2026/TAKEAWAYS.md(entry on OTel SDK 1.37 private surfaces)🤖 Filed during PR #601 wrap-up.