{"record":{"id":"998b6db6d8a45d1c","repo":"tursodatabase/turso","slug":"14","errorCode":"14","errorMessage":"SQLite Error {errorCode}: 'unable to open database file'.","messagePattern":"SQLite Error (.+?): 'unable to open database file'\\.","errorType":"exception","errorClass":"SqliteException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data.Sqlite/SqliteConnection.cs","lineNumber":756,"sourceCode":"                ? GetSharedMemoryFile(dataSource)\n                : \":memory:\";\n        if (dataSource.StartsWith(\"file:\", StringComparison.OrdinalIgnoreCase))\n            return NormalizeUriDataSource(dataSource);\n\n        const string dataDirectory = \"|DataDirectory|\";\n        if (dataSource.StartsWith(dataDirectory, StringComparison.OrdinalIgnoreCase))\n        {\n            var baseDirectory = AppDomain.CurrentDomain.GetData(\"DataDirectory\") as string\n                                ?? AppContext.BaseDirectory;\n            dataSource = Path.Combine(baseDirectory, dataSource[dataDirectory.Length..].TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));\n        }\n\n        var filename = Path.IsPathRooted(dataSource)\n            ? dataSource\n            : Path.Combine(AppContext.BaseDirectory, dataSource);\n\n        if ((options.Mode == SqliteOpenMode.ReadOnly || options.Mode == SqliteOpenMode.ReadWrite) && !File.Exists(filename))\n            throw new SqliteException(Properties.Resources.SqliteNativeError(SQLITE_CANTOPEN, \"unable to open database file\"), SQLITE_CANTOPEN);\n\n        return filename;\n    }\n\n    private static string NormalizeUriDataSource(string dataSource)\n    {\n        var queryStart = dataSource.IndexOf('?', StringComparison.Ordinal);\n        var path = queryStart < 0 ? dataSource[5..] : dataSource[5..queryStart];\n        var query = queryStart < 0 ? string.Empty : dataSource[(queryStart + 1)..];\n        foreach (var part in query.Split('&', StringSplitOptions.RemoveEmptyEntries))\n        {\n            var pieces = part.Split('=', 2);\n            if (!pieces[0].Equals(\"mode\", StringComparison.OrdinalIgnoreCase))\n                continue;\n\n            var mode = pieces.Length == 2 ? pieces[1] : string.Empty;\n            if (!mode.Equals(\"ro\", StringComparison.OrdinalIgnoreCase)\n                && !mode.Equals(\"rw\", StringComparison.OrdinalIgnoreCase)","sourceCodeStart":738,"sourceCodeEnd":774,"githubUrl":"https://github.com/tursodatabase/turso/blob/244cde92a7df7f9b8b8b7a4075c35a12977e303e/bindings/dotnet/src/Turso.Data.Sqlite/SqliteConnection.cs#L738-L774","documentation":"Thrown by NormalizeDataSource when Mode is ReadOnly or ReadWrite and the resolved database file does not exist, with SQLite code 14 (SQLITE_CANTOPEN). The check happens before open: these two modes never create files, so a missing file is reported as 'unable to open database file'. The path is resolved relative to AppContext.BaseDirectory when not rooted, not relative to the process working directory.","triggerScenarios":"Opening 'Data Source=app.db;Mode=ReadOnly' (or Mode=ReadWrite) when app.db is absent at the resolved path; using a relative filename and running from a different working directory, because the binding combines it with AppContext.BaseDirectory; '|DataDirectory|' substitution resolving to a folder without the file.","commonSituations":"Assuming the file will be created like the default ReadWriteCreate mode does; deploying an app where the .db file was not copied to the output/publish folder; relative-path bugs in test runners (dotnet test runs from bin/Debug) and single-file publishes; wrong casing of the filename on Linux.","solutions":["Use Mode=ReadWriteCreate (the default) if the database is allowed to be created on first open.","Verify the resolved path exists before connecting: Path.Combine(AppContext.BaseDirectory, relativePath) then File.Exists — remember relative paths resolve against the app base directory, not Environment.CurrentDirectory.","For read-only access to an optional file, deploy or copy the .db file to the publish output (mark it CopyToOutputDirectory in the project file) or use an absolute path."],"exampleFix":"// before\nvar conn = new SqliteConnection(\"Data Source=data/app.db;Mode=ReadOnly\");\nconn.Open(); // throws if app.db missing\n\n// after\nvar dbPath = Path.Combine(AppContext.BaseDirectory, \"data\", \"app.db\");\nif (!File.Exists(dbPath))\n    throw new FileNotFoundException(\"Database not deployed\", dbPath);\nvar conn = new SqliteConnection($\"Data Source={dbPath};Mode=ReadOnly\");","handlingStrategy":"validation","validationCode":"var path = Path.IsPathRooted(ds) ? ds : Path.Combine(AppContext.BaseDirectory, ds);\nif ((mode is SqliteOpenMode.ReadOnly or SqliteOpenMode.ReadWrite) && !File.Exists(path))\n    throw new FileNotFoundException(\"Database file missing (required by Mode).\", path);","typeGuard":null,"tryCatchPattern":"try { conn.Open(); }\ncatch (SqliteException ex) when (ex.SqliteErrorCode == 14)\n{ /* log resolved path, verify deployment, or fall back to ReadWriteCreate */ }","preventionTips":["Remember relative data sources resolve against AppContext.BaseDirectory, not the current working directory.","Mark required .db files CopyToOutputDirectory in the project, or create them with ReadWriteCreate on first run."],"tags":["csharp","dotnet","sqlite","file-not-found","connection-string"],"backgroundTag":"sqlite-cantopen","analyzedSha":"244cde92a7df7f9b8b8b7a4075c35a12977e303e","analyzedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}