tursodatabase/turso · error

path should be valid string

Error message

path should be valid string

What it means

open_mv_store() (core/storage/journal_mode.rs) derives the MVCC log path (db_path.with_extension("db-log")) and converts it to &str with .expect("path should be valid string") before io.open_file(). Rust paths are OsStr and not guaranteed UTF-8; any non-UTF-8 byte sequence in the path panics here.

Source

Thrown at core/storage/journal_mode.rs:94

    // storage must also have an encryption context so the log is not plaintext
    if let Some(storage) = &durable_storage {
        if encryption_ctx.is_some() && storage.encryption_ctx().is_none() {
            return Err(LimboError::InvalidArgument(
                    "encrypted MVCC requires the custom DurableStorage to be configured with encryption"
                        .to_string(),
                ));
        }
    }
    let storage: Arc<dyn mvcc::persistent_storage::DurableStorage> =
        if let Some(storage) = durable_storage {
            storage
        } else {
            let db_path = db_path.as_ref();
            let log_path = db_path.with_extension("db-log");
            let string_path = log_path
                .as_os_str()
                .to_str()
                .expect("path should be valid string");
            let file = io.open_file(string_path, flags, false)?;
            Arc::new(mvcc::persistent_storage::Storage::new(
                file,
                io,
                encryption_ctx,
            ))
        };

    Ok(Arc::new(MvStore::new_in(
        mvcc::MvccClock::new(),
        storage,
        allocator,
        experimental_mvcc_passive_checkpoint,
    )?))
}

View on GitHub (pinned to 244cde92a7)

Solutions

  1. Canonicalize or rename the database path to valid UTF-8 before opening in MVCC mode
  2. Validate db_path.as_os_str().to_str() in your own code and return an error instead of letting the engine panic
  3. Pass a custom DurableStorage via the durable_storage argument so the engine never stringifies the path itself
  4. Track engine updates replacing to_str() with proper error handling

Example fix

// before
let db = Database::open(io, "data\u{fffd}\u{fffd}.db".as_path(), flags, mvcc_settings)?; // non-UTF-8 bytes panic in open_mv_store

// after
let path = std::path::PathBuf::from(user_path);
if path.as_os_str().to_str().is_none() {
    return Err(format!("database path must be valid UTF-8 for MVCC: {path:?}").into());
}
let db = Database::open(io, path, flags, mvcc_settings)?;
Defensive patterns

Strategy: validation

Validate before calling

// Validate before opening in MVCC mode:
fn ensure_utf8_path(p: &std::path::Path) -> Result<&str, String> {
    p.as_os_str().to_str().ok_or_else(|| format!("path is not valid UTF-8: {p:?}"))
}
let path_str = ensure_utf8_path(&db_path)?;
// also check the derived log path turso will use:
ensure_utf8_path(&db_path.with_extension("db-log"))?;

Type guard

fn is_valid_utf8_path(p: &std::path::Path) -> bool {
    p.as_os_str().to_str().is_some()
}

Prevention

When it happens

Trigger: Opening or creating a database in experimental MVCC mode (journal_mode=mvcc) when the database path contains bytes that are not valid UTF-8 - the conversion log_path.as_os_str().to_str() returns None.

Common situations: Unix filesystems with arbitrary-byte filenames, temp directories with locale-odd names, PathBuf built from raw OS bytes, Windows paths with unpaired surrogates.

Related errors


AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20). Data as JSON: /api/errors/3c9fe66b14de785c. Report an issue: GitHub.