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
- Strip any '?query' portion from the path and supply only the local file path (e.g. /data/mydb.sqlite).
- Set read-only or other SQLite options via the extension's supported configuration, not by appending URL parameters.
- 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
- Store plain local file paths in the databaseName field
- Strip any '?options' suffix users paste from JDBC URLs
- Configure read-only via the extension, not URL parameters
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
- File path starts with illegal prefix; only local files are…
- Invalid host supplied
- SQLException::Couldn't get a Connection!
- SQLException
- URISyntaxException
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)