{"record":{"id":"0e1f57965c8f9a86","repo":"transact-rs/sqlx","slug":"filename-passed-to-sqlite-must-be-valid-utf-8","errorCode":null,"errorMessage":"filename passed to SQLite must be valid UTF-8","messagePattern":"filename passed to SQLite must be valid UTF-8","errorType":"exception","errorClass":"io::Error (InvalidData)","httpStatus":null,"severity":"error","filePath":"sqlx-sqlite/src/connection/establish.rs","lineNumber":46,"sourceCode":"    open_flags: i32,\n    busy_timeout: Duration,\n    statement_cache_capacity: usize,\n    log_settings: LogSettings,\n    #[cfg(feature = \"load-extension\")]\n    extensions: IndexMap<CString, Option<CString>>,\n    pub(crate) thread_name: String,\n    pub(crate) command_channel_size: usize,\n    #[cfg(feature = \"regexp\")]\n    register_regexp_function: bool,\n}\n\nimpl EstablishParams {\n    pub fn from_options(options: &SqliteConnectOptions) -> Result<Self, Error> {\n        let mut filename = options\n            .filename\n            .to_str()\n            .ok_or_else(|| {\n                io::Error::new(\n                    io::ErrorKind::InvalidData,\n                    \"filename passed to SQLite must be valid UTF-8\",\n                )\n            })?\n            .to_owned();\n\n        // Set common flags we expect to have in sqlite\n        let mut flags = SQLITE_OPEN_URI;\n\n        // By default, we connect to an in-memory database.\n        // [SQLITE_OPEN_NOMUTEX] will instruct [sqlite3_open_v2] to return an error if it\n        // cannot satisfy our wish for a thread-safe, lock-free connection object\n\n        flags |= if options.serialized {\n            SQLITE_OPEN_FULLMUTEX\n        } else {\n            SQLITE_OPEN_NOMUTEX\n        };","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/transact-rs/sqlx/blob/03af8bcc5711a1935580a54bea249c219a0c217d/sqlx-sqlite/src/connection/establish.rs#L28-L64","documentation":"EstablishParams::from_options converts the SqliteConnectOptions filename (a PathBuf) into a String to build the connection URL for SQLite. Because the SQLite C API path here requires UTF-8, sqlx refuses non-UTF-8 paths with this InvalidData error rather than passing lossy bytes to SQLite. It surfaces during SqlitePool::connect/connect_with when the database path is not valid UTF-8.","triggerScenarios":"Calling SqlitePool::connect / SqliteConnectOptions::new().filename(path) where the PathBuf comes from the filesystem on a platform with non-UTF-8 encoding (e.g. Latin-1 filenames on Unix) or contains invalid byte sequences.","commonSituations":"Deriving the DB path from environment variables or argv on non-UTF-8 locales; files in directories with legacy-encoded names; path constructed from raw OS bytes via OsStr::from_bytes.","solutions":["Validate the path with path.to_str() before connecting and fail with a clear user-facing message","Rename/move the database file to a UTF-8-safe path","Normalize the input: convert the OsStr via to_string_lossy only if lossy replacement is acceptable, otherwise reject","Set the process locale/environment so paths read from the OS are UTF-8"],"exampleFix":"// before\nlet opts = SqliteConnectOptions::new().filename(&user_path);\nlet pool = SqlitePool::connect_with(opts).await?;\n// after: check up front\nlet filename = user_path.to_str().ok_or_else(|| anyhow!(\"SQLite path {:?} is not valid UTF-8\", user_path))?;\nlet pool = SqlitePool::connect(&format!(\"sqlite://{filename}\")).await?;","handlingStrategy":"validation","validationCode":"use std::path::Path;\nfn ensure_utf8_path(p: &Path) -> Result<&str, String> {\n    p.to_str().ok_or_else(|| format!(\"SQLite database path {:?} is not valid UTF-8\", p))\n}","typeGuard":"fn is_utf8_path(p: &std::path::Path) -> bool {\n    p.to_str().is_some()\n}","tryCatchPattern":"match SqlitePool::connect_with(opts).await {\n    Ok(pool) => Ok(pool),\n    Err(e) if e.to_string().contains(\"must be valid UTF-8\") => {\n        Err(anyhow!(\"database path is not valid UTF-8; please move/rename the file\"))\n    }\n    Err(e) => Err(e.into()),\n}","preventionTips":["Validate paths with Path::to_str() before constructing SqliteConnectOptions","Avoid deriving DB paths from raw OS bytes or legacy-locale environment variables","Keep database filenames ASCII/UTF-8-safe in deployment configs"],"tags":["sqlite","encoding","utf-8","connection"],"backgroundTag":"invalid-utf8-path","analyzedSha":"03af8bcc5711a1935580a54bea249c219a0c217d","analyzedAt":"2026-09-03T15:01:28.752Z","contentChangedAt":"2026-09-03T15:01:28.752Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}