tursodatabase/turso · error · ArgumentException
Offset and count were out of bounds for the array.
Error message
Offset and count were out of bounds for the array.
What it means
Every Read/Write first calls ValidateBuffer, which enforces the standard bounds contract: buffer non-null, offset/count non-negative, and offset <= buffer.Length && count <= buffer.Length - offset. Any violation throws ArgumentException (Properties.Resources.InvalidOffsetAndCount) before any I/O happens, matching System.IO's span rules.
Source
Thrown at bindings/dotnet/src/Turso.Data.Sqlite/SqliteBlob.cs:158
var value = command.ExecuteScalar();
return value switch
{
byte[] bytes => bytes,
string text => Encoding.UTF8.GetBytes(text),
null or DBNull => throw new SqliteException(Properties.Resources.SqliteNativeError(1, "no such rowid: " + rowId), 1),
_ => Encoding.UTF8.GetBytes(Convert.ToString(value, System.Globalization.CultureInfo.InvariantCulture) ?? string.Empty)
};
}
private static void ValidateBuffer(byte[] buffer, int offset, int count)
{
ArgumentNullException.ThrowIfNull(buffer);
if (offset < 0)
throw new ArgumentOutOfRangeException(nameof(offset), offset, message: null);
if (count < 0)
throw new ArgumentOutOfRangeException(nameof(count), count, message: null);
if (offset > buffer.Length || count > buffer.Length - offset)
throw new ArgumentException(Properties.Resources.InvalidOffsetAndCount);
}
private static string QuoteIdentifier(string identifier)
=> "\"" + identifier.Replace("\"", "\"\"", StringComparison.Ordinal) + "\"";
}
View on GitHub (pinned to 244cde92a7)
Solutions
- Derive count from the remaining space: count = Math.Min(requested, buffer.Length - offset).
- Prefer modern APIs (stream.ReadExactly, spans/ArraySegment) that remove manual bounds math.
- When it throws, log buffer.Length/offset/count at the call site - the values are always the fastest clue.
Example fix
// before int read = blob.Read(buf, offset: 4, count: buf.Length); // 4 + buf.Length > buf.Length -> throws // after int read = blob.Read(buf, 4, buf.Length - 4);
Defensive patterns
Strategy: validation
Validate before calling
static void CheckBounds(byte[] buffer, int offset, int count) {
ArgumentNullException.ThrowIfNull(buffer);
if (offset < 0 || count < 0 || offset > buffer.Length || count > buffer.Length - offset)
throw new ArgumentException("offset/count out of bounds");
}
CheckBounds(buf, off, cnt);
blob.Read(buf, off, cnt); Prevention
- Always derive count from buffer.Length - offset.
- Use ReadExactly/span-based APIs that eliminate manual bounds math.
- Validate parsed sizes before they reach stream calls.
When it happens
Trigger: Passing a count larger than the space remaining after offset (the classic off-by-one: count = buffer.Length while offset > 0); negative offset/count from unsigned underflow or parsed input; an offset past the end of the buffer.
Common situations: Looping reads that keep an offset cursor but pass the full length as count; (buffer, 0, int.MaxValue) 'read everything' idioms; pointer-arithmetic code translated from C/C++; header-size math off by one.
Related errors
- Invalid value {origin} for enum type {SeekOrigin}.
- An attempt was made to seek before the beginning of the stre
- Resizing is not supported.
- Expected first argument to be an array of statements
- setAsciiStream length must be non-negative
AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20).
Data as JSON: /api/errors/76eb9625ae2f63ea.
Report an issue: GitHub.