tursodatabase/turso · error · InvalidOperationException

Partial sync requires exactly one prefix or query bootstrap

Error message

Partial sync requires exactly one prefix or query bootstrap strategy.

What it means

TursoPartialSyncOptions.Validate enforces that a partial sync bootstrap specifies exactly one strategy: a key-set prefix (PrefixLength) or a SQL query (Query) — never both and never neither. This InvalidOperationException is thrown when hasPrefix == hasQuery (both set or both unset).

Source

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

    }
}

public sealed class TursoPartialSyncOptions
{
    public int? PrefixLength { get; init; }
    public string? Query { get; init; }
    public long? SegmentSize { get; init; }
    public bool Prefetch { get; init; }

    internal void Validate()
    {
        if (Query is not null)
            ArgumentException.ThrowIfNullOrWhiteSpace(Query);

        var hasPrefix = PrefixLength.HasValue;
        var hasQuery = Query is not null;
        if (hasPrefix == hasQuery)
            throw new InvalidOperationException("Partial sync requires exactly one prefix or query bootstrap strategy.");
        if (PrefixLength is <= 0)
            throw new ArgumentOutOfRangeException(nameof(PrefixLength), PrefixLength, "Prefix length must be positive.");
        if (SegmentSize is <= 0)
            throw new ArgumentOutOfRangeException(nameof(SegmentSize), SegmentSize, "Segment size must be positive.");
        if (SegmentSize is { } segmentSize && (ulong)segmentSize > nuint.MaxValue)
            throw new ArgumentOutOfRangeException(nameof(SegmentSize), SegmentSize, "Segment size exceeds the native platform size.");
    }
}

public sealed class TursoSyncDatabaseOptions
{
    public TursoSyncDatabaseOptions(string path, Uri remoteUri)
    {
        ArgumentException.ThrowIfNullOrWhiteSpace(path);
        ArgumentNullException.ThrowIfNull(remoteUri);
        Path = path;
        RemoteUri = remoteUri;
    }

View on GitHub (pinned to c1e5928725)

Solutions

  1. Set exactly one of PrefixLength or Query; clear the other (leave Query null when using PrefixLength, and vice versa)
  2. If you intended a full sync, remove the TursoPartialSyncOptions entirely instead of leaving it empty
  3. If you intended a query bootstrap, remove PrefixLength (set to null)

Example fix

// before: both set
var partial = new TursoPartialSyncOptions { PrefixLength = 1024, Query = "SELECT * FROM users" };
// after: one strategy only
var partial = new TursoPartialSyncOptions { Query = "SELECT * FROM users" };
Defensive patterns

Strategy: validation

Validate before calling

bool IsValidPartialStrategy(TursoPartialSyncOptions o) =>
    (o.PrefixLength.HasValue ^ (o.Query is not null));
// before constructing:
// if (!IsValidPartialStrategy(partial)) throw new ArgumentException("Set exactly one of PrefixLength or Query.");

Try / catch

try
{
    var db = new TursoSyncDatabase(options);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("exactly one prefix or query bootstrap"))
{
    logger.LogError(ex, "Partial sync options must set exactly one of PrefixLength or Query.");
    throw;
}

Prevention

When it happens

Trigger: Creating TursoPartialSyncOptions with both PrefixLength and Query set, or with neither set (all defaults).

Common situations: Copy-pasting a sample and leaving both fields populated; forgetting to fill in either field; merging two configurations where one used prefix and the other used query.

Related errors


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