hasura/graphql-engine · error · Error

Unsupported path on ComparisonColumn: ${[...path, selector].

Error message

Unsupported path on ComparisonColumn: ${[...path, selector].join('.')}

What it means

generateComparisonColumnFragment builds the SQL expression for a ComparisonColumn in a filter. Only two path shapes are allowed: an empty path (column on the current table) or the single-element path `['$']` (column on the query's root table). Any other path — e.g. `['someRelation']` or `['a','b']` — is not supported and throws with the offending joined path.

Source

Thrown at dc-agents/sqlite/src/query.ts:336

      `${sourceTablePrefix}${escapeIdentifier(sourceColumnName)} = ${targetTableAlias}.${escapeIdentifier(targetColumnName as string)}`,
  );
}

function generateComparisonColumnFragment(
  comparisonColumn: ComparisonColumn,
  queryTableAlias: string,
  currentTableAlias: string,
): string {
  const path = comparisonColumn.path ?? [];
  const queryTablePrefix = queryTableAlias ? `${queryTableAlias}.` : '';
  const currentTablePrefix = currentTableAlias ? `${currentTableAlias}.` : '';
  const selector = getColumnSelector(comparisonColumn.name);
  if (path.length === 0) {
    return `${currentTablePrefix}${escapeIdentifier(selector)}`;
  } else if (path.length === 1 && path[0] === '$') {
    return `${queryTablePrefix}${escapeIdentifier(selector)}`;
  } else {
    throw new Error(
      `Unsupported path on ComparisonColumn: ${[...path, selector].join('.')}`,
    );
  }
}

function generateComparisonValueFragment(
  comparisonValue: ComparisonValue,
  queryTableAlias: string,
  currentTableAlias: string,
): string {
  switch (comparisonValue.type) {
    case 'column':
      return generateComparisonColumnFragment(
        comparisonValue.column,
        queryTableAlias,
        currentTableAlias,
      );
    case 'scalar':

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Drop relationship paths from comparisons; filter only on columns of the queried table (`path: []`) or the root table (`path: ['$']`)
  2. Rewrite relationship-based filters as separate relationship queries with their own filter
  3. If you need cross-table filtering, use an interpolated target with a CTE that pre-joins the tables

Example fix

// before
{ type: 'column', path: ['artist'], name: 'name', operand: ... }
// after
{ type: 'column', path: [], name: 'artist_name', operand: ... }
Defensive patterns

Strategy: validation

Validate before calling

const okPath = (p: unknown[]) => p.length === 0 || (p.length === 1 && p[0] === '$'); if (!okPath(comp.path ?? [])) throw new Error('Only empty or ["$"] paths supported');

Type guard

const isSupportedComparisonPath = (p: unknown): p is [] | ['$'] => Array.isArray(p) && (p.length === 0 || (p.length === 1 && p[0] === '$'));

Prevention

When it happens

Trigger: Sending a where/expression tree where a ComparisonColumn's `path` refers to relationships or nested paths, e.g. `{ type: 'column', path: ['artist'], name: 'name' }`, which this engine cannot resolve to a join prefix.

Common situations: Clients used to engines with path-based comparisons across relationships (Postgres/Hasura style `path` in expressions); converting filters from another connector; deeper nesting introduced by newer query API versions.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/3b1c87b1243d4d4c. Report an issue: GitHub.