{"record":{"id":"b158f4fda72a9266","repo":"tursodatabase/turso","slug":"partial-sync-requires-exactly-one-prefix-or-query","errorCode":null,"errorMessage":"Partial sync requires exactly one prefix or query bootstrap strategy.","messagePattern":"Partial sync requires exactly one prefix or query bootstrap strategy\\.","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data/TursoSyncDatabaseOptions.cs","lineNumber":89,"sourceCode":"    }\n}\n\npublic sealed class TursoPartialSyncOptions\n{\n    public int? PrefixLength { get; init; }\n    public string? Query { get; init; }\n    public long? SegmentSize { get; init; }\n    public bool Prefetch { get; init; }\n\n    internal void Validate()\n    {\n        if (Query is not null)\n            ArgumentException.ThrowIfNullOrWhiteSpace(Query);\n\n        var hasPrefix = PrefixLength.HasValue;\n        var hasQuery = Query is not null;\n        if (hasPrefix == hasQuery)\n            throw new InvalidOperationException(\"Partial sync requires exactly one prefix or query bootstrap strategy.\");\n        if (PrefixLength is <= 0)\n            throw new ArgumentOutOfRangeException(nameof(PrefixLength), PrefixLength, \"Prefix length must be positive.\");\n        if (SegmentSize is <= 0)\n            throw new ArgumentOutOfRangeException(nameof(SegmentSize), SegmentSize, \"Segment size must be positive.\");\n        if (SegmentSize is { } segmentSize && (ulong)segmentSize > nuint.MaxValue)\n            throw new ArgumentOutOfRangeException(nameof(SegmentSize), SegmentSize, \"Segment size exceeds the native platform size.\");\n    }\n}\n\npublic sealed class TursoSyncDatabaseOptions\n{\n    public TursoSyncDatabaseOptions(string path, Uri remoteUri)\n    {\n        ArgumentException.ThrowIfNullOrWhiteSpace(path);\n        ArgumentNullException.ThrowIfNull(remoteUri);\n        Path = path;\n        RemoteUri = remoteUri;\n    }","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/tursodatabase/turso/blob/c1e59287258d99b309e362a63f48822256e2f65f/bindings/dotnet/src/Turso.Data/TursoSyncDatabaseOptions.cs#L71-L107","documentation":"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).","triggerScenarios":"Creating TursoPartialSyncOptions with both PrefixLength and Query set, or with neither set (all defaults).","commonSituations":"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.","solutions":["Set exactly one of PrefixLength or Query; clear the other (leave Query null when using PrefixLength, and vice versa)","If you intended a full sync, remove the TursoPartialSyncOptions entirely instead of leaving it empty","If you intended a query bootstrap, remove PrefixLength (set to null)"],"exampleFix":"// before: both set\nvar partial = new TursoPartialSyncOptions { PrefixLength = 1024, Query = \"SELECT * FROM users\" };\n// after: one strategy only\nvar partial = new TursoPartialSyncOptions { Query = \"SELECT * FROM users\" };","handlingStrategy":"validation","validationCode":"bool IsValidPartialStrategy(TursoPartialSyncOptions o) =>\n    (o.PrefixLength.HasValue ^ (o.Query is not null));\n// before constructing:\n// if (!IsValidPartialStrategy(partial)) throw new ArgumentException(\"Set exactly one of PrefixLength or Query.\");","typeGuard":null,"tryCatchPattern":"try\n{\n    var db = new TursoSyncDatabase(options);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"exactly one prefix or query bootstrap\"))\n{\n    logger.LogError(ex, \"Partial sync options must set exactly one of PrefixLength or Query.\");\n    throw;\n}","preventionTips":["When using a prefix bootstrap, explicitly set Query = null (and vice versa)","Build partial-sync options through a single factory that enforces one strategy","Review merged configuration files for leftover fields from the other strategy"],"tags":["dotnet","configuration","partial-sync","validation"],"backgroundTag":"partial-sync-bootstrap-strategy-invalid","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"}