{"record":{"id":"cdfc90b9af39852a","repo":"windmill-labs/windmill","slug":"sql-preparation-error","errorCode":"SQL_PREPARATION_ERROR","errorMessage":"Failed to prepare query: db error: ERROR: <db error text> (prefix stripped; messageText is the prepared-query error, surfaced as a Monaco diagnostic)","messagePattern":"Failed to prepare query: db error: ERROR: <db error text> \\(prefix stripped; messageText is the prepared-query error, surfaced as a Monaco diagnostic\\)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"frontend/src/lib/monaco_workers/sqlTypePlugin.worker.js","lineNumber":700,"sourceCode":"\t\tconst originalCode = cached?.originalText ?? ''\n\t\tif (!originalCode) {\n\t\t\t// Fallback if no cached result\n\t\t\tconst originalSnapshot = super.getScriptSnapshot(fileName)\n\t\t\tif (!originalSnapshot) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t}\n\n\t\tconst sqlDiagnostics = []\n\t\tfor (const query of queries) {\n\t\t\tlet messageText = query?.prepared?.error\n\t\t\tif (typeof messageText === 'string') {\n\t\t\t\tlet queryStartIdx = originalCode.indexOf('`', (query.span?.[0] || 1) - 1) + 1\n\t\t\t\t// Create a diagnostic error for this query\n\t\t\t\tlet prefix = 'Failed to prepare query: db error: ERROR: '\n\t\t\t\tif (messageText.startsWith(prefix)) messageText = messageText.substring(prefix.length)\n\t\t\t\tconst diagnostic = {\n\t\t\t\t\tcode: 'SQL_PREPARATION_ERROR',\n\t\t\t\t\tcategory: ts.typescript.DiagnosticCategory.Error,\n\t\t\t\t\tmessageText,\n\t\t\t\t\tfile: fileName,\n\t\t\t\t\tstart: queryStartIdx,\n\t\t\t\t\tlength: query.span?.[1] ? query.span[1] - queryStartIdx - 2 : 0,\n\t\t\t\t\tsource: 'sql'\n\t\t\t\t}\n\t\t\t\tsqlDiagnostics.push(diagnostic)\n\t\t\t}\n\t\t}\n\n\t\treturn sqlDiagnostics\n\t}\n\n\tasync getSyntacticDiagnostics(fileName) {\n\t\tconst diagnostics = await super.getSyntacticDiagnostics(fileName)\n\t\treturn this._mapDiagnostics(diagnostics, fileName)\n\t}","sourceCodeStart":682,"sourceCodeEnd":718,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/monaco_workers/sqlTypePlugin.worker.js#L682-L718","documentation":"In the SQL language worker for Monaco (frontend/src/lib/monaco_workers/sqlTypePlugin.worker.js), _createSqlErrorDiagnostics converts a database-side prepared-query failure into an editor diagnostic. The raw backend message has the shape 'Failed to prepare query: db error: ERROR: <db error text>'; the worker strips that prefix and surfaces only the underlying DB messageText as a red squiggle under the offending template-literal query, tagged with code SQL_PREPARATION_ERROR.","triggerScenarios":"Editing a script/app that contains a backtick-quoted SQL query; the language service sends the query to the database to prepare it; the DB rejects it (syntax error, unknown table/column, wrong placeholder count, permission denied) and the worker builds a diagnostic from the returned messageText.","commonSituations":"Typo in SQL syntax; referencing a table or column that does not exist in the connected database; using $1/$2 placeholders inconsistent with provided args; dialect mismatch (Postgres-only syntax on MySQL connection); the preview database being unreachable or the user lacking permissions.","solutions":["Read the diagnostic message — after prefix stripping it is the raw DB error (e.g. 'column \"foo\" does not exist'); fix the SQL accordingly.","Hover over the squiggle: start/length map to the failing backtick query span in the editor.","Verify the connection's target database/dialect actually supports the SQL you wrote.","Check that placeholder count ($1…) matches your args if using parameterized queries.","If the diagnostic looks stale, retrigger analysis by editing the query — the worker only reports errors from the last prepare round."],"exampleFix":"// before\nconst q = `SELECT usernmae FROM users WHERE id = $1`\n// after (fixing the unknown column reported by the diagnostic)\nconst q = `SELECT username FROM users WHERE id = $1`","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isSqlPreparationDiagnostic(d: ts.typescript.Diagnostic): boolean {\n  return (d as { code?: number | string }).code === 'SQL_PREPARATION_ERROR' || d.source === 'sql'\n}","tryCatchPattern":"// Monaco language-service context: consume diagnostics, don't catch\nmonaco.editor.onDidChangeMarkers => {\n  const diags = monaco.editor.getModelMarkers({ owner: 'sql' })\n  for (const d of diags.filter(isSqlPreparationDiagnostic)) {\n    console.log(`SQL error at ${d.startLineNumber}: ${d.message}`)\n  }\n}","preventionTips":["Validate SQL against the same database/dialect the worker prepares against.","Keep placeholder ($1, $2) counts consistent with provided parameters.","Check table/column names against the connected schema before saving.","Reconnect the preview database if diagnostics suddenly report connection errors.","Reopen the editor after dependency/schema changes to force a fresh prepare round."],"tags":["sql","monaco","database","diagnostics","editor"],"backgroundTag":"sql-prepare-error","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"}