{"record":{"id":"79950055dc20f50a","repo":"hasura/graphql-engine","slug":"can-t-execute-table-query-for-udfs","errorCode":null,"errorMessage":"Can't execute table_query for UDFs","messagePattern":"Can't execute table_query for UDFs","errorType":"http","errorClass":"ErrorWithStatusCode","httpStatus":500,"severity":"error","filePath":"dc-agents/sqlite/src/query.ts","lineNumber":511,"sourceCode":"  aggregates: Aggregates | null,\n  wWhere: Expression | null,\n  aggregatesLimit: number | null,\n  wLimit: number | null,\n  wOffset: number | null,\n  wOrder: OrderBy | null,\n): string {\n  var tableName;\n\n  // TableNames are resolved from IDs when using NQs.\n  switch (target.type) {\n    case 'table':\n      tableName = target.name;\n      break;\n    case 'interpolated':\n      tableName = [target.id];\n      break;\n    case 'function':\n      throw new ErrorWithStatusCode(`Can't execute table_query for UDFs`, 500, {\n        target,\n      });\n  }\n\n  const tableAlias = generateTargetAlias(target);\n  const aggregateSelect = aggregates\n    ? [\n        aggregates_query(\n          allRelationships,\n          target,\n          joinInfo,\n          aggregates,\n          wWhere,\n          aggregatesLimit,\n          wOffset,\n          wOrder,\n        ),\n      ]","sourceCodeStart":493,"sourceCodeEnd":529,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/dc-agents/sqlite/src/query.ts#L493-L529","documentation":"target_query is the core SELECT/subquery builder and only handles table and interpolated targets. A target of type 'function' is rejected with ErrorWithStatusCode(500) because a UDF call cannot serve as the FROM-clause source of a table query. Reached from relationship expansion, result building, and table subqueries.","triggerScenarios":"A function target reaching the main query builder — top level, via a relationship's target, or via a subquery — after passing the earlier endpoint-level check.","commonSituations":"Nested function targets inside relationship trees; generic client code wrapping entities as function targets; API version drift.","solutions":["Use only table/interpolated targets everywhere in the request tree","Pre-validate the request tree client-side to reject function targets before the call","Materialize the function's output into a table or view"],"exampleFix":"// before\n{ target: { type: 'function', name: 'recent_orders' }, ... }\n// after\n{ target: { type: 'table', name: ['main','public','recent_orders'] }, ... }","handlingStrategy":"validation","validationCode":"if (body.target.type === 'function') throw new Error('SQLite agent cannot execute table_query for UDFs');","typeGuard":"const isQueryableTarget = (t: Target): t is TableTarget | InterpolatedTarget => t.type === 'table' || t.type === 'interpolated';","tryCatchPattern":null,"preventionTips":["Reject function targets client-side for every entity in the tree","Prefer views/tables for anything you need to query"],"tags":["sqlite","query-builder","udf","target","http-500"],"backgroundTag":"unsupported-query-target","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}