You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Declarative config: present-but-null components must build with defaults instead of raising; distinguish missing vs present-null through conversion (Linear OSS-24, finding L1).
📣 Public-facing draft — to be opened upstream in open-telemetry/opentelemetry-python. No internal references; copy verbatim.
Title: Declarative config: present-but-null component value raises instead of building with defaults
Description
In the declarative configuration package (opentelemetry-configuration), a YAML/JSON value that is present but null is indistinguishable from a completely absent key after parsing, so a present-null component fails to build.
Evidence
opentelemetry-configuration/src/opentelemetry/configuration/_conversion.py (_convert_value) returned None for any None value:
ifvalueisNone:
returnNone
Component factories select the configured component by testing value is not None, e.g. _tracer_provider.py (~L205-217):
forname, factoryin_SPAN_EXPORTER_REGISTRY.items():
value=getattr(config, name, None)
ifvalueisnotNone:
returnfactory(value)
...
raiseConfigurationError("No exporter type specified in span exporter config. ...")
The same pattern exists in _logger_provider.py, _meter_provider.py, _propagator.py, and _common.py:_resolve_component. A present-null console: converts to None, so if value is not None is false and the code raises ConfigurationError instead of building a console exporter with defaults.
Reproduction
tracer_provider:
processors:
- batch:
exporter:
console: # present but null
Raises ConfigurationError: No exporter type specified... instead of creating a ConsoleSpanExporter with defaults.
Spec
configuration/sdk.md: Parse MUST distinguish a missing key from a present-null one; a present-null component MUST be created with defaults. Java and Go bind a present-null node to the raw (empty) model node and construct with defaults.
Proposed fix
Carry a present-null indicator through conversion. Since _convert_value is only invoked for keys actually present (absent keys fall through to dataclass field defaults), a None there always means present-null. Convert it to a component-with-defaults value: a defaults-only dataclass instance for dataclass-typed fields, an empty mapping for mapping-alias fields (e.g. the console exporter), and None for primitives. Existing value is not None factory selection then fires for present-null while absent keys stay None.
Activity
ocelotl commentedon Jul 22, 2026
🔒 Internal (dash0) — not for upstream.
oss_24_declarative_config_present_null_defaults9e7d6534b· PR: oss_24_declarative_config_present_null_defaults #34ocelotl commentedon Jul 22, 2026
📣 Public-facing draft — to be opened upstream in
open-telemetry/opentelemetry-python. No internal references; copy verbatim.Title: Declarative config: present-but-null component value raises instead of building with defaults
Description
In the declarative configuration package (
opentelemetry-configuration), a YAML/JSON value that is present but null is indistinguishable from a completely absent key after parsing, so a present-null component fails to build.Evidence
opentelemetry-configuration/src/opentelemetry/configuration/_conversion.py(_convert_value) returnedNonefor anyNonevalue:Component factories select the configured component by testing
value is not None, e.g._tracer_provider.py(~L205-217):The same pattern exists in
_logger_provider.py,_meter_provider.py,_propagator.py, and_common.py:_resolve_component. A present-nullconsole:converts toNone, soif value is not Noneis false and the code raisesConfigurationErrorinstead of building a console exporter with defaults.Reproduction
Raises
ConfigurationError: No exporter type specified...instead of creating aConsoleSpanExporterwith defaults.Spec
configuration/sdk.md: Parse MUST distinguish a missing key from a present-null one; a present-null component MUST be created with defaults. Java and Go bind a present-null node to the raw (empty) model node and construct with defaults.Proposed fix
Carry a present-null indicator through conversion. Since
_convert_valueis only invoked for keys actually present (absent keys fall through to dataclass field defaults), aNonethere always means present-null. Convert it to a component-with-defaults value: a defaults-only dataclass instance for dataclass-typed fields, an empty mapping for mapping-alias fields (e.g. the console exporter), andNonefor primitives. Existingvalue is not Nonefactory selection then fires for present-null while absent keys stayNone.ocelotl commentedon Aug 7, 2026
Superseded by upstream open-telemetry#5454; PR #34 closed. Present-null-builds-with-defaults is implemented on upstream/main.