-
Notifications
You must be signed in to change notification settings - Fork 8.5k
Description
Summary
On APM error group details, transaction/span flyouts, and trace view, opening an error sample or a transaction/span that has no service or no service.environment (e.g. OpenTelemetry or incomplete data) can cause an uncaught error that crashes the error boundary.
Error: Cannot read properties of undefined (reading 'environment')
Location: Multiple files in x-pack/solutions/observability/plugins/apm/public/ where code read .environment or .service.environment without optional chaining or fallback. Stack trace points at APM chunk and shared deps (e.g. apm.chunk.*.js).
Root cause
- For OpenTelemetry (OTel) or incomplete documents, the error API can return an
errorwithoutservice, or a transaction/span withserviceundefined. The UI assumederror.service,transaction.service, orrootTransaction.servicewas always defined. - Code accessed
error.service.environment,transaction.service.environment,rootTransaction.service.environment, orconfigService.environmentwithout optional chaining. When the parent object was undefined,undefined.environmentthrew. - Same pattern in span flyout and agent configuration link:
transaction?.service.environment(missing?.onservice) orconfigService.environmentwith no guard.
When it happens
- Context: User is on APM (e.g. Error group details, Transaction details with waterfall, Span flyout, or a link that uses agent config service).
- Action: User opens an error sample, or a transaction/span flyout, or a view that uses
service.environmentfor a document that has noserviceor noservice.environment(e.g. OTel). - Result: The throw fires and the error boundary shows the crash.
It may not reproduce when all data includes service.environment (e.g. Elastic agents with environment set).
Affected locations and fix
Use optional chaining and fallback to constants from common/environment_filter_values.ts (ENVIRONMENT_NOT_DEFINED.value for missing service environment, ENVIRONMENT_ALL.value for missing query environment):
| Area | File | Change |
|---|---|---|
| Error group details | error_sample_detail.tsx | error?.service?.environment ?? transaction?.service?.environment ?? ENVIRONMENT_NOT_DEFINED.value; display with getEnvironmentLabel(errorEnvironment); guard error / error.error elsewhere |
| Error sample contextual insight | error_sample_contextual_insight.tsx | Optional chaining on error?.service; optional error / service in props |
| Sample summary | sample_summary.tsx | error?.error?.log, error?.error?.exception, error?.error?.culprit; optional error in props |
| Transaction flyout | flyout_top_level_properties.tsx | transaction.service?.environment ?? ENVIRONMENT_NOT_DEFINED.value, query?.environment ?? ENVIRONMENT_ALL.value |
| View full trace link | maybe_view_trace_link.tsx | rootTransaction.service?.environment ?? ENVIRONMENT_NOT_DEFINED.value |
| Span flyout sticky props | sticky_span_properties.tsx | transaction?.service?.environment ?? ENVIRONMENT_NOT_DEFINED.value |
| Agent config link | agent_configuration_links.tsx | configService?.environment ?? ENVIRONMENT_NOT_DEFINED.value, configService?.name |
Suggested fix
- In all locations above: use optional chaining on the object that may be undefined (e.g.
error?.service?.environment,transaction?.service?.environment,configService?.environment). - Where a string is required (e.g. for
getNextEnvironmentUrlParamor display), fall back toENVIRONMENT_NOT_DEFINED.valuewhen the service has no environment, and toENVIRONMENT_ALL.valuewhen the URL query has no environment, matching existing patterns in resolve_url_params, agent_instances_details, and environment_filter_values. - For error sample detail, display environment with
getEnvironmentLabel(errorEnvironment)so "Not defined" is shown when the value isENVIRONMENT_NOT_DEFINED.value.