OpenRefine/OpenRefine · error · IllegalArgumentException

Paths to SQLite databases are not allowed to contain '?'

Error message

Paths to SQLite databases are not allowed to contain '?'

What it means

SQLiteConnectionManager.getDatabaseUrl builds the SQLite JDBC URL from the configured database path and rejects paths containing '?'. A '?' would start the JDBC connection-parameter section of the URL, letting the path inject options (like open_mode) that would break the read-only hardening, so it is refused up front.

Solutions

  1. Strip any '?query' portion from the path and supply only the local file path (e.g. /data/mydb.sqlite).
  2. Set read-only or other SQLite options via the extension's supported configuration, not by appending URL parameters.
  3. Validate the configured path in your form/config before invoking the connection.

Example fix

// before
dbConfig.setDatabaseName("jdbc:sqlite:/tmp/testdb.sqlite?mode=ro");
// after
dbConfig.setDatabaseName("/tmp/testdb.sqlite");
Defensive patterns

Strategy: validation

Validate before calling

public static void validateSqlitePath(String path) {
  if (path == null || path.contains("?")) throw new IllegalArgumentException("SQLite path must not contain '?'");
}
validateSqlitePath(dbPath); dbConfig.setDatabaseName(dbPath);

Type guard

boolean isValidSqlitePath(String p) { return p != null && !p.contains("?"); }

Try / catch

try { service.openConnection(dbConfig); } catch (IllegalArgumentException e) { /* strip query part and retry */ }

Prevention

When it happens

Trigger: Creating a SQLite connection whose DatabaseConfiguration.databaseName contains a literal '?' character, e.g. a URL-style path "jdbc:sqlite:/tmp/db?mode=ro" pasted into the filename field.

Common situations: Users pasting full JDBC URLs or web URLs into the SQLite database path field; config files holding parameterized paths; copy-paste mistakes from other SQLite tooling.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of OpenRefine/OpenRefine@a946177e04 (2026-09-08). Data as JSON: /api/errors/547d0d97aabcd51f. Report an issue: GitHub.

Appendix: source

Thrown at extensions/database/src/com/google/refine/extension/database/sqlite/SQLiteConnectionManager.java:74

    /**
     * Create a new instance of this connection manager.
     *
     * @return an instance of the manager
     */
    public static SQLiteConnectionManager getInstance() {
        if (instance == null) {
            if (logger.isDebugEnabled()) {
                logger.debug("::Creating new SQLite ConnectionManager ::");
            }
            instance = new SQLiteConnectionManager();
        }
        return instance;
    }

    public static String getDatabaseUrl(DatabaseConfiguration dbConfig) {
        String dbPath = dbConfig.getDatabaseName();
        if (dbPath.contains("?")) {
            throw new IllegalArgumentException("Paths to SQLite databases are not allowed to contain '?'");
        }
        if (dbPath.startsWith("//") || dbPath.startsWith("\\\\") || dbPath.startsWith("\\/") || dbPath.startsWith("/\\")) {
            throw new IllegalArgumentException("File path starts with illegal prefix; only local files are accepted.");
        }
        if (!new File(dbPath).isFile()) {
            throw new IllegalArgumentException("File could not be read: " + dbPath);
        }
        try {
            URI uri = new URI(
                    "jdbc:" + dbConfig.getDatabaseType().toLowerCase(),
                    dbPath + "?open_mode=1&limit_attached=0", // open_mode=1 means read-only
                    null);
            return uri.toASCIIString();
        } catch (URISyntaxException e) {
            throw new IllegalArgumentException(e);
        }
    }

View on GitHub (pinned to a946177e04)