windmill-labs/windmill · error

${extractErrorMessage(result)}

Error message

${extractErrorMessage(result)}

What it means

The datatable proxy executes each incoming SQL query by running a preview PostgreSQL script on the Windmill workspace (runScriptPreview) and polling the job. If the job completes without success, the server extracts the error message from the job result and surfaces it to the SQL client as a PostgreSQL protocol error. This wraps any SQL execution failure on the Windmill side — bad SQL, missing datatable, permission or resource problems.

Source

Thrown at cli/src/commands/datatable/serve.ts:780

  const content = `-- raw_output\n${await prepareQueryForDatatableProxy(
    workspaceId,
    datatableName,
    query,
  )}`;

  const jobId = await wmill.runScriptPreview({
    workspace: workspaceId,
    requestBody: {
      content,
      language: "postgresql",
      args: { database: `datatable://${datatableName}` },
    },
  });

  const { result, success } = await pollJobWithQueueLogging(workspaceId, jobId);

  if (!success) {
    throw createPgProtocolError(extractErrorMessage(result));
  }

  return coerceEnvelope(result);
}

async function prepareQueryForDatatableProxy(
  workspaceId: string,
  datatableName: string,
  query: string,
): Promise<string> {
  if (!queryTouchesVirtualDatabaseCatalog(query)) {
    return query;
  }

  let databaseNames = [datatableName];
  if (query.toLowerCase().includes("pg_database")) {
    try {
      const items = await wmill.listDataTables({

View on GitHub (pinned to e474e8803c)

Solutions

  1. Read the embedded message — it is the actual error from the Windmill script run (e.g. Postgres syntax error) and fix the SQL accordingly.
  2. Verify the datatable name and workspace: run `wmill datatable list` / check the table exists in the UI.
  3. Check the worker/job logs in the Windmill UI for the failed preview script to see the full stack.
  4. Confirm you are logged into the correct workspace (`wmill workspace current`) and have permission to run scripts there.

Example fix

-- before
SELECT * FROM custumers LIMIT 10;

-- after
SELECT * FROM customers LIMIT 10;
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const res = await client.query(sql);
} catch (e) {
  // message is the raw Windmill job error; log it and inspect the failed
  // preview-script job in the Windmill UI for the full stack
  console.error('datatable query failed:', e.message);
  throw e;
}

Prevention

When it happens

Trigger: runQueryEnvelope polls a script-preview job with pollJobWithQueueLogging and receives success=false; extractErrorMessage(result) is thrown verbatim. Causes include invalid SQL syntax, referencing a non-existent table/datatable, the workspace or datatable path being wrong, and worker execution failures.

Common situations: Typo'd SQL sent from psql/DBeaver through the proxy; querying a datatable that was deleted or renamed; the connected user lacking permission to run preview scripts in the workspace; worker queue failures/timeouts surfacing as SQL errors.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/719e16622a06d9a8. Report an issue: GitHub.