tursodatabase/turso · error
Error: cannot open "{}" – {}
Error message
Error: cannot open "{}" – {} What it means
Thrown by read_sql_file, the .read dot-command, when File::open on the given path fails; the OS error (No such file or directory, Permission denied, Is a directory) is appended to the message (cli/app.rs:2068). It fires before any line is read, so no script statements have executed.
Source
Thrown at cli/app.rs:2084
fn clone_database(&mut self, output_file: &str) -> anyhow::Result<()> {
use std::path::Path;
if Path::new(output_file).exists() {
anyhow::bail!("Refusing to overwrite existing file: {output_file}");
}
let io: Arc<dyn turso_core::IO> = Arc::new(turso_core::PlatformIO::new()?);
let db = Database::open_file(io.clone(), output_file, Arc::new(SqliteDialect))?;
let target = db.connect()?;
let mut applier = ApplyWriter::new(&target);
Self::dump_database_from_conn(false, self.conn.clone(), &mut applier, StderrProgress)?;
applier.finish()?;
Ok(())
}
fn read_sql_file(&mut self, path: &str) -> anyhow::Result<()> {
let file =
File::open(path).map_err(|e| anyhow!("Error: cannot open \"{}\" – {}", path, e))?;
let reader = BufReader::new(file);
let mut query_buffer = String::new();
let mut state = ReadState::default();
for line in reader.lines() {
let line = line
.map_err(|e| anyhow!("Error: file \"{}\" is not valid UTF-8 text – {}", path, e))?;
if !query_buffer.is_empty() {
query_buffer.push('\n');
}
query_buffer.push_str(&line);
state.process(&line);
if state.is_complete() {
self.run_query(&query_buffer);View on GitHub (pinned to 492c4a71cd)
Solutions
- Check the exact path shown in the message exists (ls it)
- Use an absolute path, or a path relative to the shell's current working directory
- Fix permissions (chmod/chown) if the OS error is Permission denied
- Quote paths that contain spaces
Example fix
-- before .read scripts/init.sql -- ERROR: cannot open "scripts/init.sql" -- after .read /work/repo/scripts/init.sql
Defensive patterns
Strategy: validation
Validate before calling
let p = std::path::Path::new(path);
anyhow::ensure!(p.is_file(), "{} is not a readable file", p.display()); Prevention
- Check the path exists and is a file before invoking .read
- Prefer absolute paths in scripts that drive the CLI
- Quote paths containing spaces
When it happens
Trigger: `.read missing.sql`; a relative path resolved against a different working directory; a file without read permission; a path that points at a directory.
Common situations: Relative paths resolved from where tursodb was launched rather than where the script lives; typos; permission-restricted mounts in containers; unquoted paths containing spaces.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Error: file "{}" is not valid UTF-8 text – {}
- Failed to read manual page: {}
- Manual page not found: {page_name}
- Could not determine home directory
- Error setting Ctrl-C handler
AI-assisted analysis of tursodatabase/turso@492c4a71cd (2026-08-20).
Data as JSON: /api/errors/49ddbfc3e3fb520d.
Report an issue: GitHub.