hasura/graphql-engine · error · Error

makePerformExistsSubquery: only table relationships currentl

Error message

makePerformExistsSubquery: only table relationships currently supported

What it means

Thrown while evaluating an exists expression (type 'exists', in_table.type 'related') whose relationship target is not a table. The reference agent's query engine can only run exists subqueries against concrete table targets, so any other relationship target type hits the default branch and errors immediately.

Source

Thrown at dc-agents/reference/src/query.ts:327

      targetName: TargetName,
      query: Query,
    ) => QueryResponse,
  ) =>
  (exists: ExistsExpression, row: Record<string, RawScalarValue>): boolean => {
    const [targetTable, joinExpression] = (() => {
      switch (exists.in_table.type) {
        case 'related':
          const relationship = findRelationship(exists.in_table.relationship);
          const joinExpression = createFilterExpressionForRelationshipJoin(
            row,
            relationship,
          );
          const relationshipTarget = relationship.target;
          switch (relationshipTarget.type) {
            case 'table':
              return [relationshipTarget.name, joinExpression];
            default:
              throw new Error(
                'makePerformExistsSubquery: only table relationships currently supported',
              );
          }
        case 'unrelated':
          return [exists.in_table.table, undefined];
        default:
          return unreachable(exists.in_table['type']);
      }
    })();

    if (joinExpression === null) return false;

    const subquery: Query = {
      aggregates: {
        count: { type: 'star_count' },
      },
      limit: 1, // We only need one row to exist to satisfy this expresion, this short circuits some filtering
      where:

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Inspect the schema for the relationship referenced in exists.in_table.relationship and confirm its target is { type: 'table', name: ... }.
  2. If you control the QueryRequest, rewrite the exists expression to use in_table: { type: 'unrelated', table: '...' } with an explicit where clause instead of a non-table related target.
  3. Upgrade/patch the connector backend so it only produces table-typed relationship targets.

Example fix

// before
where: {
  type: 'exists',
  in_table: { type: 'related', relationship: 'nonTableRel' },
  where: { type: 'equal', ... },
}

// after
where: {
  type: 'exists',
  in_table: { type: 'unrelated', table: 'Album' },
  where: { type: 'and', expressions: [joinClause, { type: 'equal', ... }] },
}
Defensive patterns

Strategy: validation

Validate before calling

const rel = schema.table_relationships[table]?.[existsExpr.in_table.relationship];
if (rel?.target.type !== 'table') throw new Error('unsupported relationship target for exists');

Type guard

const isTableTarget = (t: { type: string } | undefined): t is { type: 'table'; name: string } =>
  t?.type === 'table';

Prevention

When it happens

Trigger: A QueryRequest where filter contains { type: 'exists', in_table: { type: 'related', relationship: 'r' } } and the named relationship's target type is anything other than 'table' in the schema/static data.

Common situations: Custom connector backends that emit non-table relationship targets; malformed or hand-built QueryRequest JSON; schema metadata drift where a relationship target type changed between versions.

Related errors


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