SeaQL/sea-orm · error

Fail to parse database URL

Error message

Fail to parse database URL

What it means

DbBackend::is_prefix_of parses base_url as a Url to compare its scheme against the backend, and uses .expect("Fail to parse database URL") — so any base_url string that is not a valid URL causes a panic. The method's contract requires a parseable base_url.

Solutions

  1. Ensure base_url includes a full scheme (postgres://, postgresql://, mysql:// or sqlite://)
  2. Validate with Url::parse(base_url).is_ok() before calling is_prefix_of
  3. Fix the env/config value supplying the URL (e.g. append the missing scheme)

Example fix

// before
if DbBackend::Postgres.is_prefix_of(&db_url) { ... } // panics if db_url malformed
// after
fn is_pg(url: &str) -> bool {
    Url::parse(url).map(|u| matches!(u.scheme(), "postgres" | "postgresql")).unwrap_or(false)
}
Defensive patterns

Strategy: validation

Validate before calling

use url::Url;
fn valid_db_url(s: &str) -> bool {
    Url::parse(s).map(|u| matches!(u.scheme(), "postgres" | "postgresql" | "mysql" | "sqlite")).unwrap_or(false)
}
// if !valid_db_url(&base_url) { return Err(...); }

Type guard

fn parse_db_url(s: &str) -> Option<url::Url> { Url::parse(s).ok() }

Try / catch

// avoid the expect by parsing first
match Url::parse(base_url) {
    Ok(u) => { /* proceed with scheme comparison */ }
    Err(e) => return Err(MyError::BadBaseUrl(e)),
}

Prevention

When it happens

Trigger: Calling db_backend.is_prefix_of(base_url) with a string that Url::parse rejects — empty string, missing scheme ("localhost/db"), malformed scheme, or invalid characters.

Common situations: Reading a database URL from env/config where it may be unset or relative (scheme omitted); typos in the URL; passing a filesystem path instead of a URL.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of SeaQL/sea-orm@e29bcd1b41 (2026-09-10). Data as JSON: /api/errors/abd8fc57f5bd149e. Report an issue: GitHub.

Appendix: source

Thrown at sea-orm-sync/src/database/db_connection.rs:821

    /// Panics if [DbConn] is not a SQLite connection.
    #[cfg(feature = "sqlx-sqlite")]
    pub fn get_sqlite_connection_pool(&self) -> &sqlx::SqlitePool {
        match &self.inner {
            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => &conn.pool,
            _ => panic!("Not SQLite Connection"),
        }
    }
}

impl DbBackend {
    /// Check if the URI is the same as the specified database backend.
    /// Returns true if they match.
    ///
    /// # Panics
    ///
    /// Panics if `base_url` cannot be parsed as `Url`.
    pub fn is_prefix_of(self, base_url: &str) -> bool {
        let base_url_parsed = Url::parse(base_url).expect("Fail to parse database URL");
        match self {
            Self::Postgres => {
                base_url_parsed.scheme() == "postgres" || base_url_parsed.scheme() == "postgresql"
            }
            Self::MySql => base_url_parsed.scheme() == "mysql",
            Self::Sqlite => base_url_parsed.scheme() == "sqlite",
        }
    }

    /// Build an SQL [Statement]
    pub fn build<S>(&self, statement: &S) -> Statement
    where
        S: StatementBuilder,
    {
        statement.build(self)
    }

    /// Check if the database supports `RETURNING` syntax on insert and update

View on GitHub (pinned to e29bcd1b41)