tursodatabase/turso · error · ArgumentException
The sync remote URL must not include a query string or fragm
Error message
The sync remote URL must not include a query string or fragment.
What it means
GetNormalizedRemoteUri rejects a RemoteUri that carries a query string (?key=value) or a fragment (#anchor). Sync URLs must identify only the remote database endpoint; the library builds its own request URIs and any query or fragment would corrupt them. The check runs before any network call, when the options are validated or normalized.
Source
Thrown at bindings/dotnet/src/Turso.Data/TursoSyncDatabaseOptions.cs:128
public Uri RemoteUri { get; }
public string? AuthToken { get; init; }
public string ClientName { get; init; } = "turso-sync-dotnet";
public TimeSpan? LongPollTimeout { get; init; }
public bool BootstrapIfEmpty { get; init; } = true;
public TursoPartialSyncOptions? PartialSync { get; init; }
public TursoRemoteEncryptionOptions? RemoteEncryption { get; init; }
public long? PushOperationsThreshold { get; init; }
public long? PullBytesThreshold { get; init; }
public bool ForceLogicalMvccPull { get; init; }
public HttpClient? HttpClient { get; init; }
public string? ExperimentalFeatures { get; init; }
internal Uri GetNormalizedRemoteUri()
{
if (!RemoteUri.IsAbsoluteUri)
throw new ArgumentException("The sync remote URL must be absolute.", nameof(RemoteUri));
if (!string.IsNullOrEmpty(RemoteUri.Query) || !string.IsNullOrEmpty(RemoteUri.Fragment))
throw new ArgumentException("The sync remote URL must not include a query string or fragment.", nameof(RemoteUri));
if (!string.IsNullOrEmpty(RemoteUri.UserInfo))
throw new ArgumentException("Use AuthToken instead of embedding credentials in the sync URL.", nameof(RemoteUri));
if (string.IsNullOrEmpty(RemoteUri.Host))
throw new ArgumentException("The sync remote URL must include a host.", nameof(RemoteUri));
var scheme = RemoteUri.Scheme.ToLowerInvariant() switch
{
"turso" or "libsql" => Uri.UriSchemeHttps,
"http" => Uri.UriSchemeHttp,
"https" => Uri.UriSchemeHttps,
_ => throw new ArgumentException(
"The sync remote URL must use turso, libsql, HTTP, or HTTPS.",
nameof(RemoteUri)),
};
var builder = new UriBuilder(RemoteUri)
{
Scheme = scheme,
Port = RemoteUri.IsDefaultPort ? -1 : RemoteUri.Port,View on GitHub (pinned to c1e5928725)
Solutions
- Strip the '?' query and '#' fragment from the remote URL before passing it as RemoteUri.
- Move any token that was placed in the query string into the AuthToken option instead.
- Recreate the Uri with only scheme, host, port, and path components (e.g. new Uri(builder.Scheme + builder.Host + builder.Path)).
Example fix
// before
var opts = new TursoSyncDatabaseOptions(path, new Uri("https://mydb.turso.io?token=abc"));
// after
var opts = new TursoSyncDatabaseOptions(path, new Uri("https://mydb.turso.io")) { AuthToken = "abc" }; Defensive patterns
Strategy: validation
Validate before calling
static void EnsureNoQueryOrFragment(Uri remoteUri)
{
if (!remoteUri.IsAbsoluteUri) throw new ArgumentException("URL must be absolute");
if (!string.IsNullOrEmpty(remoteUri.Query) || !string.IsNullOrEmpty(remoteUri.Fragment))
throw new ArgumentException($"Sync URL must not contain query/fragment: {remoteUri}");
} Type guard
static bool IsCleanSyncUrl(Uri u) => u.IsAbsoluteUri && string.IsNullOrEmpty(u.Query) && string.IsNullOrEmpty(u.Fragment) && string.IsNullOrEmpty(u.UserInfo);
Try / catch
try { var db = new TursoSyncDatabase(opts); }
catch (ArgumentException ex) when (ex.ParamName == nameof(TursoSyncDatabaseOptions.RemoteUri))
{
// fix URL: strip query/fragment, then retry
} Prevention
- Never append tokens or options as query parameters to the sync URL; use AuthToken and options properties.
- Normalize URLs once in a shared factory that strips '?' and '#' before constructing options.
- Log the RemoteUri in a startup assertion test so bad URLs surface in CI, not production.
When it happens
Trigger: Constructing TursoSyncDatabaseOptions (or calling TursoSyncDatabase/configuration paths that invoke GetNormalizedRemoteUri/Validate) with a RemoteUri such as https://host/db?slug=foo or https://host/db#frag. Uri.Query or Uri.Fragment is non-empty at TursoSyncDatabaseOptions.cs:127-128.
Common situations: Pasting a Turso web-console URL that includes query parameters, appending API keys or tokens to the URL as query parameters, copying a URL with an anchor from documentation or a browser address bar, template code that appends database names as '?database=x'.
Related errors
- The sync remote URL must include a host.
- The sync remote URL must use turso, libsql, HTTP, or HTTPS.
- Use AuthToken instead of embedding credentials in the sync U
- Automatic sync is not supported for embedded replica connect
- Turso sync operations cannot be reentered from the sync HTTP
AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-31).
Data as JSON: /api/errors/3efa98523be6a0f7.
Report an issue: GitHub.