langfuse/langfuse · warning · Error

Position-in-trace filters are not supported in postgres

Error message

Position-in-trace filters are not supported in postgres

What it means

positionInTrace filters (latency/position conditions like 'first in trace' or 'root span') rely on ClickHouse window functions and have no Postgres translation, so filterToPrisma throws for this type. It is one of three explicitly unsupported filter types on Postgres, alongside categoryOptions and booleanObject.

Source

Thrown at packages/shared/src/server/filterToPrisma.ts:125

          ", ",
        )}] `;
        break;
      case "boolean":
        valuePrisma = Prisma.sql`${filter.value}`;
        break;
      case "categoryOptions":
        // LFE-4815: Support category options in postgres
        logger.warn("Category options not supported in postgres yet");
        throw new Error("Category options not supported in postgres yet");
      case "booleanObject":
        logger.warn("Boolean object filters not supported in postgres yet");
        throw new Error("Boolean object filters not supported in postgres yet");
      case "null":
        valuePrisma = Prisma.sql``;
        break;
      case "positionInTrace":
        logger.warn("Position-in-trace filters are not supported in postgres");
        throw new Error("Position-in-trace filters not supported in postgres");
    }
    const jsonKeyPrisma =
      filter.type === "stringObject" || filter.type === "numberObject"
        ? Prisma.sql`->>${filter.key}`
        : Prisma.empty;
    const [cast1, cast2] =
      filter.type === "numberObject"
        ? [Prisma.raw("cast("), Prisma.raw(" as double precision)")]
        : [Prisma.empty, Prisma.empty];
    const [valuePrefix, valueSuffix] =
      filter.type === "string" || filter.type === "stringObject"
        ? [
            ["contains", "does not contain", "ends with"].includes(
              filter.operator,
            )
              ? Prisma.raw("'%' || ")
              : Prisma.empty,
            ["contains", "does not contain", "starts with"].includes(

View on GitHub (pinned to 59d92c7cf3)

Solutions

  1. Drop the positionInTrace filter from the request or use ClickHouse-backed storage
  2. Re-express the query without positional semantics (e.g. filter on parentObservationId is null for root spans) where equivalent
  3. Hide/disable positionInTrace filter options in UIs when running against Postgres storage

Example fix

// before
filters: [{ type: 'positionInTrace', column: 'position', operator: 'equals', value: 'first' }]

// after
filters: [{ type: 'string', column: 'parentObservationId', operator: 'equals', value: 'none' }] // root-span approximation
Defensive patterns

Strategy: validation

Validate before calling

const POSTGRES_UNSUPPORTED = new Set(['categoryOptions', 'booleanObject', 'positionInTrace']);
filters = filters.filter(f => f.type !== 'positionInTrace'); // postgres deployments

Type guard

const isPostgresSupportedFilter = (f: Filter) => !['categoryOptions','booleanObject','positionInTrace'].includes(f.type);

Try / catch

try { query({ filters }); } catch (e) { if (/Position-in-trace filters are not supported/.test(e.message)) { fall back to parentObservationId-based filtering; } throw e; }

Prevention

When it happens

Trigger: Requesting observations/spans filtered by positionInTrace (e.g. filterType 'positionInTrace' with operator like 'first'/'last') on a Postgres-backed deployment; common when a saved trace-detail view from a ClickHouse deployment is replayed against Postgres.

Common situations: Postgres-storage self-hosted installs using trace explorer filters like 'first event in trace' or 'root observation'; frontend code paths that unconditionally offer these filters regardless of storage backend.

Related errors


AI-assisted analysis of langfuse/langfuse@59d92c7cf3 (2026-08-27). Data as JSON: /api/errors/264293acb57716cd. Report an issue: GitHub.