pinpoint-apm/pinpoint · warning

TRANSACTION_LIST.LINKED_TRANSACTION_NOT_FOUND

Error message

TRANSACTION_LIST.LINKED_TRANSACTION_NOT_FOUND

What it means

A toast warning shown when the OTEL trace-to-Pinpoint transaction link button cannot resolve the linked transaction. The code fetches the trace's span metadata rows; if no row has an applicationName or serviceType, it cannot build the transaction search URL, so it warns instead of navigating.

Solutions

  1. Verify the trace metadata API returns rows with applicationName and serviceType populated for the given traceId/spanId
  2. Check that the OTEL collector/pinpoint is mapping service.name and service.type resource attributes correctly
  3. Retry the link after the trace is fully processed (data may still be ingesting)
  4. Fall back to searching the transaction manually from the transaction list

Example fix

// before
const preferred = rows.find((row) => String(row.spanId) === spanId) || rows[0];
if (!preferred?.applicationName || !preferred?.serviceType) {
  toast.warn(t('TRANSACTION_LIST.LINKED_TRANSACTION_NOT_FOUND'));
  return;
}
// after
const preferred = rows.find((row) => String(row.spanId) === spanId) || rows[0];
if (!preferred?.applicationName || !preferred?.serviceType) {
  toast.warn(t('TRANSACTION_LIST.LINKED_TRANSACTION_NOT_FOUND'));
  // optionally: fall back to first row that HAS application info
  const anyValid = rows.find((r) => r.applicationName && r.serviceType);
  if (!anyValid) return;
  preferred = anyValid;
}
Defensive patterns

Strategy: fallback

Validate before calling

const rows = data?.metadata ?? [];
const preferred = rows.find((r) => String(r.spanId) === spanId) || rows[0];
const linkable = !!preferred?.applicationName && !!preferred?.serviceType;

Type guard

const isLinkableRow = (row?: { applicationName?: string; serviceType?: string }): row is { applicationName: string; serviceType: string } =>
  typeof row?.applicationName === 'string' && row.applicationName.length > 0 &&
  typeof row?.serviceType === 'string' && row.serviceType.length > 0;

Prevention

When it happens

Trigger: Clicking the OTEL link button on a transaction whose trace metadata is empty, or whose resolved preferred row (span matching the link's spanId, else the first row) lacks applicationName or serviceType.

Common situations: OTLP traces ingested without application/service attributes; the linked spanId points to a sub-span whose row is missing; stale link to a trace that no longer has metadata rows; partially ingested trace data.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/bf831dff1cebf16e. Report an issue: GitHub.

Appendix: source

Thrown at web-frontend/src/main/v3/packages/ui/src/components/Transaction/call-tree/callTreeTableColumns.tsx:780

  // 않고, 열린 화면이 전역 선택값으로 조회한다(`resolveRequestService`).
  const { serviceName } = useTransactionSearchParameters();

  const handleClick = async (e: React.MouseEvent) => {
    e.stopPropagation();
    // fetch errors already surface via the global query error toast
    const data = await queryClient
      .fetchQuery(getTransactionTraceMetadataQueryOptions(traceId))
      .catch(() => null);
    if (data === null) {
      return;
    }
    const rows = data?.metadata ?? [];

    // A trace may contain multiple spans (multi-application); prefer the span the
    // link points to, falling back to the first row (e.g. link target is a sub-span).
    const preferred = rows.find((row) => String(row.spanId) === spanId) || rows[0];
    if (!preferred?.applicationName || !preferred?.serviceType) {
      toast.warn(t('TRANSACTION_LIST.LINKED_TRANSACTION_NOT_FOUND'));
      return;
    }

    const baseTime = preferred.collectorAcceptTime;
    const from = formatInTimeZone(baseTime - 150000, timezone, SEARCH_PARAMETER_DATE_FORMAT);
    const to = formatInTimeZone(baseTime + 150000, timezone, SEARCH_PARAMETER_DATE_FORMAT);
    const path = getTransactionListPath(
      { applicationName: preferred.applicationName, serviceType: preferred.serviceType },
      undefined,
      serviceName,
    );
    const url = `${BASE_PATH}${path}?${convertParamsToQueryString({
      from,
      to,
      traceInfo: traceId,
      transactionInfo: JSON.stringify({
        agentId: preferred.agentId,
        spanId: preferred.spanId,

View on GitHub (pinned to 744c3d3075)