tursodatabase/turso · error · ArgumentException

The sync remote URL must include a host.

Error message

The sync remote URL must include a host.

What it means

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.

Source

Thrown at bindings/dotnet/src/Turso.Data/TursoSyncDatabaseOptions.cs:132

    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,
            UserName = string.Empty,
            Password = string.Empty,
        };
        return builder.Uri;

View on GitHub (pinned to c1e5928725)

Solutions

  1. Supply the full remote URL including host, e.g. https://mydb.turso.io.
  2. Check the config/env value feeding RemoteUri is the remote database URL, not the local file path (that goes in the `path` constructor argument).

Example fix

// before
var opts = new TursoSyncDatabaseOptions(localPath, new Uri("file:///data/app.db"));
// after
var opts = new TursoSyncDatabaseOptions(localPath, new Uri("https://mydb.turso.io"));
Defensive patterns

Strategy: validation

Validate before calling

static void EnsureHostPresent(Uri remoteUri)
{
    if (string.IsNullOrEmpty(remoteUri.Host))
        throw new ArgumentException("Sync URL must include a host, e.g. https://mydb.turso.io");
}

Type guard

static bool HasHost(Uri u) => u.IsAbsoluteUri && !string.IsNullOrEmpty(u.Host);

Try / catch

try { var db = new TursoSyncDatabase(opts); }
catch (ArgumentException ex) when (ex.Message.Contains("must include a host"))
{
    // fix configuration: local path goes in 'path', remote URL in RemoteUri
}

Prevention

When it happens

Trigger: 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.

Common situations: 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").

Related errors


AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-31). Data as JSON: /api/errors/ae75939953211e88. Report an issue: GitHub.