tursodatabase/turso · warning · InvalidOperationException
Parameter index {index} is too large.
Error message
Parameter index {index} is too large. What it means
BindNamedParameter resolves a parameter name to its native 1-based position via StatementNamedPosition. Positions below 1 mean the name does not exist and the method silently returns 0 without binding; a position above int.MaxValue instead throws InvalidOperationException. SQLite's variable limit sits orders of magnitude below int.MaxValue, so in practice this throw signals a corrupted or ABI-mismatched native return rather than a realistic parameter count.
Source
Thrown at bindings/dotnet/src/Turso.Raw/Public/TursoBindings.cs:176
public static void BindParameter(TursoStatementHandle statement, int index, TursoValue parameter)
{
statement.ThrowIfInvalid();
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(index);
BindParameterAt(statement, index, parameter);
}
public static int BindNamedParameter(TursoStatementHandle statement, string name, TursoValue parameter)
{
statement.ThrowIfInvalid();
ArgumentNullException.ThrowIfNull(name);
var index = TursoInterop.StatementNamedPosition(statement, name);
if (index < 1)
return 0;
if (index > int.MaxValue)
throw new InvalidOperationException($"Parameter index {index} is too large.");
BindParameterAt(statement, (int)index, parameter);
return (int)index;
}
public static bool Read(TursoStatementHandle statement)
=> Read(statement, runExternalIo: null);
public static bool Read(TursoStatementHandle statement, Action? runExternalIo)
{
statement.ThrowIfInvalid();
while (true)
{
var status = TursoInterop.StatementStep(statement, out var errorPtr);
if (status == TursoStatusCode.Row)
return true;
if (status == TursoStatusCode.Done)View on GitHub (pinned to 6c72522679)
Solutions
- Verify the named parameter exists before relying on binding: check the return value of BindNamedParameter (0 means the name was not found) and enumerate names with GetParameterName.
- Match native library and managed binding versions (same release set) so the position contract holds.
- Use positional BindParameter with indexes from GetParameterCount when names are not required.
- If it throws with a modest statement, capture SQL and parameter names and report it as a bindings/native mismatch bug.
Defensive patterns
Strategy: validation
Validate before calling
// verify the name exists before relying on the binding
int pos = TursoInterop.StatementNamedPosition(statement, name); // or use the BindNamedParameter return value
if (TursoBindings.BindNamedParameter(statement, name, value) == 0)
throw new InvalidOperationException($"Parameter {name} not found on statement"); Try / catch
try { TursoBindings.BindNamedParameter(stmt, name, value); }
catch (InvalidOperationException ex) when (ex.Message.Contains("too large")) { /* native/managed version mismatch: realign packages */ } Prevention
- Treat a 0 return from BindNamedParameter as a missing-name bug, not success.
- Keep native library and managed bindings versions in lockstep.
- Prefer positional binding when parameter identity is under your control.
When it happens
Trigger: A native turso library whose StatementNamedPosition returns a garbage/huge value — typically after mixing bindings and native library versions; hypothetically a generated statement with more than 2^31-1 parameters, which the engine would reject anyway.
Common situations: Upgrading the managed NuGet package without shipping the matching native library (or vice versa); custom interop shims changing the position return contract. The far more common gotcha nearby is the silent return-0 path: a typo'd parameter name simply never binds.
Related errors
- statement is invalid
- Only finite numbers (not Infinity or NaN) can be passed as a
- Unsupported argument type: {value.GetType()}
- database is invalid
- Unable to read native value bytes.
AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-08-20).
Data as JSON: /api/errors/8fd3573af57f764c.
Report an issue: GitHub.