{"record":{"id":"435b09600677e8b7","repo":"Budibase/budibase","slug":"readablemessage","errorCode":null,"errorMessage":"${readableMessage}","messagePattern":"\\$\\{readableMessage\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/server/src/integrations/microsoftSqlServer.ts","lineNumber":388,"sourceCode":"        for (let binding of query.bindings) {\n          request.input(`p${count++}`, binding)\n        }\n      }\n      // this is a hack to get the inserted ID back,\n      //  no way to do this with Knex nicely\n      const sql =\n        operation === Operation.CREATE\n          ? `${query.sql}; SELECT SCOPE_IDENTITY() AS id;`\n          : query.sql\n      this.log(sql, query.bindings)\n      return await request.query(sql)\n    } catch (err: any) {\n      let readableMessage = getReadableErrorMessage(\n        SourceName.SQL_SERVER,\n        err.number\n      )\n      if (readableMessage) {\n        throw new Error(readableMessage, { cause: err })\n      } else {\n        throw new Error(err.message as string, { cause: err })\n      }\n    }\n  }\n\n  getDefinitionSQL(tableName: string, schemaName: string): SqlQuery {\n    return {\n      sql: `select *\n            from INFORMATION_SCHEMA.COLUMNS\n            where TABLE_NAME=@p0 AND TABLE_SCHEMA=@p1`,\n      bindings: [tableName, schemaName],\n    }\n  }\n\n  getConstraintsSQL(tableName: string, schemaName: string): SqlQuery {\n    return {\n      sql: `SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/integrations/microsoftSqlServer.ts#L370-L406","documentation":"internalQuery() runs SQL against SQL Server and maps driver errors to human-readable messages via getReadableErrorMessage(SourceName.SQL_SERVER, err.number). When the error's number matches a known SQL Server error code, it throws a new Error with that readable message, chaining the original error as cause.","triggerScenarios":"Any SQL Server error raised during query execution whose err.number is in the readable-message mapping — most commonly constraint violations (duplicate key), syntax errors, permission denials, or missing object errors returned by tedious.","commonSituations":"Running a query that inserts a duplicate primary key or violates a foreign key; referencing a nonexistent table/column; a user without SELECT/INSERT permissions; malformed SQL generated by the query builder.","solutions":["Read the readableMessage — it is the mapped SQL Server error — and fix the SQL or data it describes","For duplicate-key errors, deduplicate rows or change the conflicting key values","For permission errors, grant the SQL user the required privileges","If the message is unhelpful, inspect error.cause for the original tedious error with full details"],"exampleFix":"// before: duplicate key from re-running an insert\nINSERT INTO users (id, email) VALUES (1, 'a@example.com')\n// after: make it idempotent\nIF NOT EXISTS (SELECT 1 FROM users WHERE id = 1) INSERT INTO users (id, email) VALUES (1, 'a@example.com')","handlingStrategy":"try-catch","validationCode":"// validate before executing: check the target object exists\nconst exists = await internalQuery({ sql: \"SELECT 1 FROM sys.tables WHERE name = @tableName\", bindings: [tableName] })\nif (!exists.length) throw new Error(`Table ${tableName} does not exist in SQL Server`)","typeGuard":"function hasSqlNumber(err: unknown): err is { number: number; message: string } {\n  return typeof err === \"object\" && err !== null && typeof (err as any).number === \"number\"\n}","tryCatchPattern":"try {\n  return await ds.query(sqlQuery)\n} catch (err) {\n  // message is the mapped readable message; original tedious error is on cause\n  if (/duplicate key/i.test(err.message)) {\n    // handle conflict: retry with new key or upsert\n  }\n  console.error(\"SQL Server error:\", (err as any).cause)\n  throw err\n}","preventionTips":["Design keys/constraints so duplicate-key violations are unlikely; handle them explicitly","Check object names and permissions before deploying queries","Always inspect err.cause for the underlying SQL Server error number","Use parameterized queries to avoid syntax errors from interpolated values"],"tags":["sql-server","query","error-mapping","readable-error"],"backgroundTag":"sql-query-error","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}