Budibase/budibase · error · Error

${err.message}

Error message

${err.message}

What it means

internalQuery() runs SQL against SQL Server and first tries getReadableErrorMessage(SourceName.SQL_SERVER, err.number). If the driver error's number is not in the mapping (readableMessage is falsy), the integration rethrows the raw driver message via new Error(err.message, { cause: err }), preserving the original error as cause.

Source

Thrown at packages/server/src/integrations/microsoftSqlServer.ts:390

        }
      }
      // this is a hack to get the inserted ID back,
      //  no way to do this with Knex nicely
      const sql =
        operation === Operation.CREATE
          ? `${query.sql}; SELECT SCOPE_IDENTITY() AS id;`
          : query.sql
      this.log(sql, query.bindings)
      return await request.query(sql)
    } catch (err: any) {
      let readableMessage = getReadableErrorMessage(
        SourceName.SQL_SERVER,
        err.number
      )
      if (readableMessage) {
        throw new Error(readableMessage, { cause: err })
      } else {
        throw new Error(err.message as string, { cause: err })
      }
    }
  }

  getDefinitionSQL(tableName: string, schemaName: string): SqlQuery {
    return {
      sql: `select *
            from INFORMATION_SCHEMA.COLUMNS
            where TABLE_NAME=@p0 AND TABLE_SCHEMA=@p1`,
      bindings: [tableName, schemaName],
    }
  }

  getConstraintsSQL(tableName: string, schemaName: string): SqlQuery {
    return {
      sql: `SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
            INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU
              ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY' 

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Inspect error.cause (the original driver error) for the real SQL Server error number and details
  2. Fix the underlying SQL/data issue indicated by the raw message
  3. Increase the request timeout for long-running queries
  4. If the code deserves a friendly message, add it to the SQL_SERVER readable-error mapping
Defensive patterns

Strategy: try-catch

Validate before calling

// no pre-call validation exists for unmapped errors; bound execution time instead
const query = { sql: "SELECT ...", timeout: 30000 }

Type guard

function isUnmappedDriverError(err: unknown): err is { message: string; cause?: unknown } {
  return err instanceof Error && typeof (err as any).number !== "number"
}

Try / catch

try {
  return await ds.query(sqlQuery)
} catch (err) {
  // raw driver message; original error chained as cause
  const original = (err as any).cause
  if (original?.code === "ETIMEOUT" || /timeout/i.test(err.message)) {
    // retry with a longer timeout
  }
  throw err
}

Prevention

When it happens

Trigger: Any SQL Server execution error whose err.number has no entry in the readable-error mapping — uncommon SQL Server codes, timeouts, deadlocks, connection drops mid-query, or driver-level errors where err.number is undefined.

Common situations: Query timeouts on long-running statements; deadlock victims; connection reset while streaming results; newly encountered SQL Server error codes not yet mapped in Budibase's readable-error table.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/481e46454f97f398. Report an issue: GitHub.