hasura/graphql-engine · error · ErrorWithStatusCode
`escapeTargetName` only implemented for tables and interpola
Error message
`escapeTargetName` only implemented for tables and interpolated queries
What it means
escapeTargetName switches on the target type and only knows how to escape `'table'` and `'interpolated'` targets (the latter via its CTE id). Any other target type — in practice `'function'` — falls into the default branch and throws an ErrorWithStatusCode(500).
Source
Thrown at dc-agents/sqlite/src/query.ts:103
}
/**
*
* @param tableName: Unescaped table name. E.g. 'Alb"um'
* @returns Escaped table name. E.g. '"Alb\"um"'
*/
export function escapeTableName(tableName: TableName): string {
return validateTableName(tableName).map(escapeIdentifier).join('.');
}
export function escapeTargetName(target: Target): string {
switch (target.type) {
case 'table':
return escapeTableName(target.name);
case 'interpolated':
return escapeTableName([target.id]); // Interpret as CTE reference
default:
throw new ErrorWithStatusCode(
'`escapeTargetName` only implemented for tables and interpolated queries',
500,
{ target },
);
}
}
/**
* @param tableName
* @returns escaped tableName string with schema qualification removed
*
* This is useful in where clauses in returning statements where a qualified table name is invalid SQLite SQL.
*/
export function escapeTableNameSansSchema(tableName: TableName): string {
return escapeTableName(getTableNameSansSchema(tableName));
}
export function json_object(View on GitHub (pinned to 724551b9ae)
Solutions
- Ensure every target in the request tree (including nested/relationship targets) is a table or interpolated target
- Upgrade the agent — function targets should be rejected earlier with a clearer message
- If you control the server, extend escapeTargetName rather than letting it hit default
Example fix
// before: nested function target
{ type: 'function', name: 'udf' }
// after
{ type: 'table', name: ['main','public','materialized_view'] } Defensive patterns
Strategy: validation
Validate before calling
function assertQueryableTargetTree(q: any) { walk(q, t => { if (t?.type !== 'table' && t?.type !== 'interpolated') throw new Error(`Unsupported target: ${t?.type}`); }); } Type guard
const isEscapableTarget = (t: Target): t is TableTarget | InterpolatedTarget => t.type === 'table' || t.type === 'interpolated';
Prevention
- Walk the whole request tree (nested targets too), not just the top-level target
- Add a client-side JSON-schema check on requests before dispatch
When it happens
Trigger: A query with a function target reaching WHERE-clause, subquery, join, or aggregate-subquery generation because it bypassed the earlier top-level type check (e.g. nested inside a relationship or reused target object).
Common situations: Function targets sneaking in through relationship traversal or nested query fragments rather than the top-level body; version drift between the request schema and the query builder's supported target kinds.
Related errors
- Unsupported field type "object"
- Unsupported field type "array"
- Can't create alias for functions
- Can't execute table_query for UDFs
- User defined functions not supported in queries
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/454cd34c3a5b6722.
Report an issue: GitHub.