{"record":{"id":"ae75939953211e88","repo":"tursodatabase/turso","slug":"the-sync-remote-url-must-include-a-host","errorCode":null,"errorMessage":"The sync remote URL must include a host.","messagePattern":"The sync remote URL must include a host\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data/TursoSyncDatabaseOptions.cs","lineNumber":132,"sourceCode":"    public bool BootstrapIfEmpty { get; init; } = true;\n    public TursoPartialSyncOptions? PartialSync { get; init; }\n    public TursoRemoteEncryptionOptions? RemoteEncryption { get; init; }\n    public long? PushOperationsThreshold { get; init; }\n    public long? PullBytesThreshold { get; init; }\n    public bool ForceLogicalMvccPull { get; init; }\n    public HttpClient? HttpClient { get; init; }\n    public string? ExperimentalFeatures { get; init; }\n\n    internal Uri GetNormalizedRemoteUri()\n    {\n        if (!RemoteUri.IsAbsoluteUri)\n            throw new ArgumentException(\"The sync remote URL must be absolute.\", nameof(RemoteUri));\n        if (!string.IsNullOrEmpty(RemoteUri.Query) || !string.IsNullOrEmpty(RemoteUri.Fragment))\n            throw new ArgumentException(\"The sync remote URL must not include a query string or fragment.\", nameof(RemoteUri));\n        if (!string.IsNullOrEmpty(RemoteUri.UserInfo))\n            throw new ArgumentException(\"Use AuthToken instead of embedding credentials in the sync URL.\", nameof(RemoteUri));\n        if (string.IsNullOrEmpty(RemoteUri.Host))\n            throw new ArgumentException(\"The sync remote URL must include a host.\", nameof(RemoteUri));\n\n        var scheme = RemoteUri.Scheme.ToLowerInvariant() switch\n        {\n            \"turso\" or \"libsql\" => Uri.UriSchemeHttps,\n            \"http\" => Uri.UriSchemeHttp,\n            \"https\" => Uri.UriSchemeHttps,\n            _ => throw new ArgumentException(\n                \"The sync remote URL must use turso, libsql, HTTP, or HTTPS.\",\n                nameof(RemoteUri)),\n        };\n        var builder = new UriBuilder(RemoteUri)\n        {\n            Scheme = scheme,\n            Port = RemoteUri.IsDefaultPort ? -1 : RemoteUri.Port,\n            UserName = string.Empty,\n            Password = string.Empty,\n        };\n        return builder.Uri;","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/tursodatabase/turso/blob/c1e59287258d99b309e362a63f48822256e2f65f/bindings/dotnet/src/Turso.Data/TursoSyncDatabaseOptions.cs#L114-L150","documentation":"GetNormalizedRemoteUri requires the RemoteUri to have a host component. A URL without a host (e.g. just a scheme and path) cannot identify the remote sync endpoint, so the library throws instead of silently syncing against an empty host.","triggerScenarios":"Constructing TursoSyncDatabaseOptions with a RemoteUri such as new Uri(\"file:///local/db\") or a file-only/path-only absolute URI where Uri.Host is empty at TursoSyncDatabaseOptions.cs:131-132.","commonSituations":"Passing a local file path or file:// URI instead of a remote URL, building the URI from an empty or malformed config value, typos that drop the host (\"https:///path\").","solutions":["Supply the full remote URL including host, e.g. https://mydb.turso.io.","Check the config/env value feeding RemoteUri is the remote database URL, not the local file path (that goes in the `path` constructor argument)."],"exampleFix":"// before\nvar opts = new TursoSyncDatabaseOptions(localPath, new Uri(\"file:///data/app.db\"));\n// after\nvar opts = new TursoSyncDatabaseOptions(localPath, new Uri(\"https://mydb.turso.io\"));","handlingStrategy":"validation","validationCode":"static void EnsureHostPresent(Uri remoteUri)\n{\n    if (string.IsNullOrEmpty(remoteUri.Host))\n        throw new ArgumentException(\"Sync URL must include a host, e.g. https://mydb.turso.io\");\n}","typeGuard":"static bool HasHost(Uri u) => u.IsAbsoluteUri && !string.IsNullOrEmpty(u.Host);","tryCatchPattern":"try { var db = new TursoSyncDatabase(opts); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"must include a host\"))\n{\n    // fix configuration: local path goes in 'path', remote URL in RemoteUri\n}","preventionTips":["Keep the local file path (constructor 'path') and the remote URL (RemoteUri) clearly separate in config.","Validate the remote URL at config load time, before constructing options.","Use URL parsing in tests to assert host presence for every environment's sync URL."],"tags":["dotnet","sync","url-validation","argument-exception"],"backgroundTag":"invalid-sync-url","analyzedSha":"c1e59287258d99b309e362a63f48822256e2f65f","analyzedAt":"2026-08-31T11:17:35.598Z","contentChangedAt":"2026-08-31T11:17:35.598Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}