SonarSource/sonarqube · error · IllegalStateException

Error during processing of row: [%s]

Error message

Error during processing of row: [%s]

What it means

SelectImpl.list reads all rows of a migration-time SQL query into a list, converting each row via the given RowReader. If reading any row throws (bad type conversion, unexpected null, driver error), the row contents are embedded in 'Error during processing of row: [%s]' and rethrown to pinpoint the offending data. The finally block always closes the ResultSet and the select.

Source

Thrown at server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/step/SelectImpl.java:48

public class SelectImpl extends BaseSqlStatement<Select> implements Select {

  private SelectImpl(PreparedStatement pstmt) {
    super(pstmt);
  }

  @Override
  public <T> List<T> list(Select.RowReader<T> reader) throws SQLException {
    ResultSet rs = pstmt.executeQuery();
    Select.Row row = new Select.Row(rs);
    try {
      List<T> rows = new ArrayList<>();
      while (rs.next()) {
        rows.add(reader.read(row));
      }
      return rows;
    } catch (Exception e) {
      throw newExceptionWithRowDetails(row, e);
    } finally {
      DatabaseUtils.closeQuietly(rs);
      close();
    }
  }

  @Override
  public <T> T get(Select.RowReader<T> reader) throws SQLException {
    ResultSet rs = pstmt.executeQuery();
    Select.Row row = new Select.Row(rs);
    try {
      if (rs.next()) {
        return reader.read(row);
      }
      return null;
    } catch (Exception e) {
      throw newExceptionWithRowDetails(row, e);
    } finally {

View on GitHub (pinned to 184c821202)

Solutions

  1. Inspect the embedded row data in the message to find the corrupt/unexpected value.
  2. Fix or delete the offending row directly in the database (with a backup) before re-running the migration.
  3. Verify the RowReader mapping matches the actual column types in the SELECT.
  4. Restore from backup if the schema was manually modified.

Example fix

// before
String name = row.getString(2); // column may be NULL -> exception
// after
String name = row.isNull(2) ? null : row.getString(2);
Defensive patterns

Strategy: try-catch

Validate before calling

-- SQL: inspect rows before migrating
SELECT * FROM <table> WHERE <mapped_column> IS NULL OR <mapped_column> !~ '^[0-9]+$';

Try / catch

try {
  List<MyDto> rows = select().column(...).rows(reader);
} catch (Exception e) {
  LOG.error("Migration aborted; offending row embedded in message: " + e.getMessage(), e);
  throw e; // migration steps must fail loudly
}

Prevention

When it happens

Trigger: During a db-migration step, rs.next() succeeds but RowReader.read(row) throws — e.g. row.getLong/getString on a column with unexpected type, NULL in a non-null-expecting column, or malformed data left by a previous schema state.

Common situations: Upgrading SonarQube across versions where a table contains legacy/corrupt rows; column type drift between schema versions; hand-edited database rows; custom migration steps with wrong reader mapping.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/8855d3fe18489295. Report an issue: GitHub.