SonarSource/sonarqube · error · java.lang.IllegalStateException
Fail to execute %n (caught error, original was )
Error message
Fail to execute %s %n (caught %s error, original was %s)
What it means
DdlChange.execute wraps SQLExceptions from running a DDL statement in an IllegalStateException. When the SQL was auto-corrected or retried (e.g. Oracle ORA-01442 column-already-NOT-NULL handling strips NOT NULL and retries), the message includes the retry count and the original SQL, formatted as "Fail to execute <sql> (caught <n> error, original was <original>)".
Solutions
- Read the wrapped cause (the SQLException and its vendor code) to find the real database error.
- Inspect the printed original vs executed SQL to spot what the retry logic changed.
- Check DB user privileges and whether the migration is being re-run on a schema already migrated by a newer version.
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check for Oracle NOT NULL redundancy to avoid the retry path failing again // SELECT NULLABLE FROM user_tab_columns WHERE table_name=? AND column_name=? -> if 'Y', skip NOT NULL add
Try / catch
try {
ddl.execute(context);
} catch (IllegalStateException e) {
Throwable root = e.getCause();
if (root instanceof SQLException se) {
LOG.error("DDL failed (vendor code {}): {}", se.getErrorCode(), se.getMessage());
}
throw e;
} Prevention
- Inspect the wrapped SQLException vendor code, not just the wrapper message.
- Compare the 'original was' SQL against the executed SQL to see retries applied.
- Restore schema to a clean pre-migration state before re-running steps.
When it happens
Trigger: A DDL step's SQL throws a SQLException that the retry logic (errorCount > 0 or modified SQL) could not ultimately resolve — the second/final attempt also failed.
Common situations: Oracle migrations where a column is already NOT NULL and the retry with stripped NOT NULL still fails; syntax or permission errors on partially-migrated schemas; schema drift between environments.
Related errors
- Fail to execute
- Unsupported database dialect:
- Unsupported DB:
- Column with autoincrement is neither BigInteger, Integer…
- Error during processing of row
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/4b0a9a0c976d14f4.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/step/DdlChange.java:106
private void execute(String original, String sql, int errorCount) {
try (Statement stmt = writeConnection.createStatement()) {
stmt.execute(sql);
writeConnection.commit();
} catch (SQLException e) {
if (errorCount < ERROR_HANDLING_THRESHOLD) {
String message = e.getMessage();
if (message.contains("ORA-01451")) {
String newSql = nullPattern.matcher(sql).replaceFirst("");
execute(original, newSql, errorCount + 1);
return;
} else if (message.contains("ORA-01442")) {
String newSql = notNullPattern.matcher(sql).replaceFirst("");
execute(original, newSql, errorCount + 1);
return;
}
}
throw new IllegalStateException(messageForIseOf(original, sql, errorCount), e);
} catch (Exception e) {
throw new IllegalStateException(messageForIseOf(original, sql, errorCount), e);
}
}
private static String messageForIseOf(String original, String sql, int errorCount) {
if (!original.equals(sql) || errorCount > 0) {
return format("Fail to execute %s %n (caught %s error, original was %s)", sql, errorCount, original);
} else {
return format("Fail to execute %s", sql);
}
}
@Override
public void execute(String... sqls) {
execute(asList(sqls));
}
View on GitHub (pinned to 184c821202)