t8y2/dbx · warning · IllegalArgumentException

unsafe

Error message

unsafe

What it means

In the autotrace/explain path, before executing the SQL the plugin calls isSafeAutotraceSql(sql) and rejects anything it deems unsafe with this bare IllegalArgumentException. Autotrace executes the statement and then inspects the plan, so the SQL must pass the plugin's safety check (e.g. a single top-level statement, no disallowed constructs) to avoid executing arbitrary/multi-statement input.

Source

Thrown at plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java:1462

        String schema,
        int timeoutSecs,
        String mode
    ) throws Exception {
        Connection conn = openConnection(connection);
        applyExecutionContext(connection, conn, database, schema);

        boolean autotrace = "autotrace".equalsIgnoreCase(mode);
        String planText = null;
        String dmMethod = null;

        if (!autotrace && isOracleConnection(connection)) {
            planText = getOracleExplainInfo(conn, sql, timeoutSecs);
            dmMethod = "oracle-plan-table";
        }

        if (autotrace) {
            if (!isSafeAutotraceSql(sql)) {
                throw new IllegalArgumentException("unsafe");
            }
            // ── Autotrace mode: execute SQL first, then getExplainInfo(stmt) ──
            boolean monitorEnabled = false;
            try (Statement s = conn.createStatement()) {
                s.execute("SF_SET_SESSION_PARA_VALUE('MONITOR_SQL_EXEC', 1)");
                monitorEnabled = true;
            } catch (Exception ignored) {}

            try {
                try (Statement stmt = conn.createStatement()) {
                    if (timeoutSecs >= 0) {
                        try { stmt.setQueryTimeout(timeoutSecs); } catch (SQLFeatureNotSupportedException | UnsupportedOperationException ignored) {}
                    }
                    boolean hasResultSet = stmt.execute(trimStatementSql(sql));
                    if (hasResultSet) {
                        try (ResultSet rs = stmt.getResultSet()) {
                            while (rs.next()) { /* consume */ }
                        }

View on GitHub (pinned to c0390bff16)

Solutions

  1. Strip comments, trailing semicolons, and extra whitespace; supply exactly one statement to autotrace.
  2. Run autotrace on a plain single SELECT/statement that the safety checker accepts; validate your SQL against the same rules beforehand.
  3. Split multi-statement scripts and autotrace each statement individually.
  4. If a legitimate single statement is rejected, simplify syntax toward standard SQL or check the isSafeAutotraceSql implementation for its exact accepted pattern.

Example fix

// before
sql = "SET enable_seqscan = off; SELECT * FROM t;";  // multiple statements
autotrace(conn, sql);
// after
sql = "SELECT * FROM t";                              // single safe statement
autotrace(conn, sql);
Defensive patterns

Strategy: validation

Validate before calling

// Java: pre-check that SQL is a single clean statement before autotrace
static void assertAutotraceSafe(String sql) {
    String s = sql.strip();
    while (s.endsWith(";")) s = s.substring(0, s.length() - 1).strip();
    if (s.contains(";")) throw new IllegalArgumentException("autotrace requires exactly one statement");
    if (!s.toUpperCase(java.util.Locale.ROOT).startsWith("SELECT")
        && !s.toUpperCase(java.util.Locale.ROOT).startsWith("WITH"))
        throw new IllegalArgumentException("autotrace expects a single query");
}

Try / catch

try {
    plugin.autotrace(conn, sql);
} catch (IllegalArgumentException e) {
    if ("unsafe".equals(e.getMessage())) {
        log.warn("SQL rejected by autotrace safety check: " + summarize(sql));
        plan = plugin.explain(conn, sql); // fall back to plain EXPLAIN
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Requesting autotrace (or explain with autotrace enabled) on SQL that fails isSafeAutotraceSql: multiple statements separated by semicolons, comments or trailing junk the checker doesn't accept, non-query statements, or SQL with constructs the safety regex forbids.

Common situations: Pasting multi-statement scripts into an autotrace request, SQL containing leading comments or newlines that break the safety pattern, ORM-generated SQL with trailing semicolons, or dialect-specific syntax the checker treats as unsafe.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/93fbdbab99d4eb2e. Report an issue: GitHub.