{"record":{"id":"2b1de8acfeaa9d3b","repo":"windmill-labs/windmill","slug":"failed-to-get-ducklake-schema-json-of-result","errorCode":null,"errorMessage":"Failed to get Ducklake schema: <json of result>","messagePattern":"Failed to get Ducklake schema: <json of result>","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/dbOps.ts","lineNumber":545,"sourceCode":"}: {\n\tworkspace: string\n\tducklake: string\n\ttag?: string\n}): Promise<DBSchema> {\n\tlet result = await runScriptAndPollResult({\n\t\tworkspace,\n\t\trequestBody: {\n\t\t\tlanguage: 'duckdb',\n\t\t\tcontent: `ATTACH 'ducklake://${ducklake}' AS __ducklake__; ${DUCKLAKE_GET_SCHEMA_QUERY}`,\n\t\t\targs: {},\n\t\t\ttag\n\t\t}\n\t})\n\tlet schemas = Array.isArray(result) && result.length && (result?.[0]?.['result'] ?? {})\n\t// Safety for agent workers (duckdb ffi lib used to return JSON as stringified json)\n\tif (typeof schemas === 'string') schemas = JSON.parse(schemas)\n\n\tif (!schemas) throw new Error('Failed to get Ducklake schema: ' + JSON.stringify(result))\n\tassert('schemas is an object', typeof schemas === 'object')\n\tlet schema: Omit<SQLSchema, 'stringified'> = {\n\t\tschema: schemas,\n\t\tpublicOnly: false,\n\t\tlang: 'ducklake'\n\t}\n\treturn { ...schema, stringified: stringifySchema(schema) }\n}\n\n// Returns every schema in the ducklake (including empty ones, e.g. freshly created)\n// as a nested map { schema: { table: { column: {...} } } }.\nconst DUCKLAKE_GET_SCHEMA_QUERY = `\nSELECT json_group_object(schema_name, COALESCE(schema_data, json_object())) AS result FROM (\n\tSELECT\n\t\ts.schema_name,\n\t\t(\n\t\t\tSELECT json_group_object(table_name, table_data) FROM (\n\t\t\t\tSELECT","sourceCodeStart":527,"sourceCodeEnd":563,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/dbOps.ts#L527-L563","documentation":"getDucklakeSchema() queries the Ducklake catalog for its schema; it accepts either an array of result rows or, defensively, a stringified-JSON payload (legacy duckdb-ffi behavior). If after normalization the schemas value is empty/falsy (empty array, null result, or unparsable payload) it throws with the raw JSON of the result for debugging.","triggerScenarios":"Ducklake/duckdb query returned zero rows or an error payload instead of a schema result — e.g. the ducklake attachment does not exist, the internal DB is not initialized, or the duckdb ffi returned an unexpected shape that the string-parse fallback also failed to salvage.","commonSituations":"Querying schema before any internal DB/ducklake attachment is created; a duckdb-wasm/ffi version change altered the result shape; the underlying duckdb query failed silently and its error text ended up in `result`, making schemas falsy.","solutions":["Inspect the JSON in the error message — it usually contains the actual duckdb error; fix that root cause first.","Ensure the ducklake database is attached/initialized (run an internal DB operation that creates it) before requesting the schema.","Check the duckdb/ducklake client version matches what the app expects; result-shape changes break the parse.","Retry after the workspace's internal DB finishes provisioning if it was just created."],"exampleFix":"// before\nconst schema = await getDucklakeSchema(workspace) // throws if ducklake not attached\n// after\nawait ensureInternalDbInitialized(workspace) // attach ducklake first\nconst schema = await getDucklakeSchema(workspace)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isSchemaResult(result: unknown): boolean {\n  const r = Array.isArray(result) ? result[0]?.['result'] : result\n  const s = typeof r === 'string' ? safeParse(r) : r\n  return s != null && typeof s === 'object'\n}","tryCatchPattern":"try {\n  const schema = await getDucklakeSchema(workspace)\n} catch (e) {\n  if (e.message.startsWith('Failed to get Ducklake schema')) {\n    console.error('raw ducklake result:', e.message) // includes the JSON payload\n    await ensureInternalDbInitialized(workspace)\n  } else throw e\n}","preventionTips":["Initialize/attach the ducklake database before any schema query.","Pin duckdb client versions; result-shape changes break the parser.","Log the JSON payload from the error to find the underlying duckdb error.","Handle provisioning races after workspace creation with a short retry."],"tags":["duckdb","ducklake","schema","parsing"],"backgroundTag":"empty-query-result","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}