We recently spent a while chasing what looked like a pgvector limitation and it turned out to be something more general, so sharing in case it helps others — and to ask if this is intended behavior.
Any string parameter longer than 8000 characters passed to a raw SQL query (SqlList/SqlScalar/ExecuteSql with anonymous params) gets silently truncated to exactly 8000 chars on PostgreSQL — no exception, no warning.
Repro (ServiceStack.OrmLite.PostgreSQL 10.0.6, Npgsql, .NET 10):
var db = new OrmLiteConnectionFactory(connStr, PostgreSqlDialect.Provider).Open();
var longText = new string('x', 9000);
var roundTrip = db.SqlScalar<string>("SELECT @s::text", new { s = longText });
// roundTrip.Length == 8000 — silently truncated
What we believe is happening: StringConverter’s parameterless ctor defaults StringLength = 8000, and InitDbParam sets p.Size = StringLength on any string parameter without an explicit size. Npgsql honors Size by truncating longer values, so anything past 8000 chars is quietly dropped.
How we hit it: passing pgvector embeddings as @embedding::vector — a 3072-dim embedding’s string form is ~60KB, so it truncated to 8000 and Postgres reported 22P02: invalid input syntax for type vector: "[...0.6" (the value ends mid-float at the 8000-char mark). Small vectors work fine as parameters, so for a long time we thought vectors simply couldn’t be parameterized and interpolated them into the SQL string instead. The case that worries us more is a plain long text value written through a raw UPDATE — the truncated value is valid, so the row just silently loses its tail.
Our workaround is adding the parameter via a command filter with p.Size = value.Length, which works fine.
Is this intended behavior for PostgreSQL, and is there a supported way to opt out per-provider? What surprised us is that the provider’s own PostgreSqlStringConverter maps string columns to limitless TEXT, so we didn’t expect an 8000-char cap on the parameter side.