{"record":{"id":"bf768b6c03f2445e","repo":"tursodatabase/turso","slug":"the-sync-remote-url-must-be-absolute","errorCode":null,"errorMessage":"The sync remote URL must be absolute.","messagePattern":"The sync remote URL must be absolute\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data/TursoSyncDatabaseOptions.cs","lineNumber":126,"sourceCode":"\n    public string Path { get; }\n    public Uri RemoteUri { get; }\n    public string? AuthToken { get; init; }\n    public string ClientName { get; init; } = \"turso-sync-dotnet\";\n    public TimeSpan? LongPollTimeout { get; init; }\n    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        {","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/tursodatabase/turso/blob/c1e59287258d99b309e362a63f48822256e2f65f/bindings/dotnet/src/Turso.Data/TursoSyncDatabaseOptions.cs#L108-L144","documentation":"GetNormalizedRemoteUri validates the configured RemoteUri before constructing the sync database. A relative URI has no scheme/host to build HTTP requests against, so it throws ArgumentException('The sync remote URL must be absolute.', nameof(RemoteUri)).","triggerScenarios":"Creating TursoSyncDatabaseOptions(path, new Uri(\"myserver.example.com\")) — note Uri treats strings without a scheme as relative — or passing a value from config/env that lacks the https:// prefix.","commonSituations":"Reading the remote from an environment variable or appsettings value where the scheme was omitted; assuming Uri would infer https; string concatenation dropping the prefix.","solutions":["Prefix the value with https:// (or turso://) before creating the Uri","Use Uri.TryCreate with UriKind.Absolute and fail fast with a clear config error","Validate configuration at startup so missing schemes are caught before sync is attempted"],"exampleFix":"// before: relative URI\nvar options = new TursoSyncDatabaseOptions(path, new Uri(\"my-db.turso.io\"));\n// after: absolute URI\nvar options = new TursoSyncDatabaseOptions(path, new Uri(\"https://my-db.turso.io\"));","handlingStrategy":"validation","validationCode":"if (!Uri.TryCreate(remoteUrl, UriKind.Absolute, out var remoteUri) || !remoteUri.IsAbsoluteUri)\n    throw new ArgumentException($\"Sync remote URL '{remoteUrl}' must be absolute (include the scheme, e.g. https://).\", nameof(remoteUrl));","typeGuard":null,"tryCatchPattern":"try\n{\n    var db = new TursoSyncDatabase(options);\n}\ncatch (ArgumentException ex) when (ex.Message.Contains(\"sync remote URL must be absolute\"))\n{\n    logger.LogError(ex, \"Configured RemoteUri '{Remote}' is not an absolute URI; add the scheme.\", remoteUrl);\n    throw;\n}","preventionTips":["Store full URLs including the https:// scheme in config/env, never bare hostnames","Parse with Uri.TryCreate(..., UriKind.Absolute, ...) at configuration load time","Fail fast at startup by constructing options eagerly rather than lazily on first sync"],"tags":["dotnet","configuration","url","argument-validation"],"backgroundTag":"relative-url-not-allowed","analyzedSha":"c1e59287258d99b309e362a63f48822256e2f65f","analyzedAt":"2026-08-31T11:17:35.598Z","contentChangedAt":"2026-08-31T11:17:35.598Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}