{"id":"22fced60b6487f03","repo":"jackc/pgx","slug":"invalid-write-to-large-object","errorCode":null,"errorMessage":"invalid write to large object","messagePattern":"invalid write to large object","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"large_objects.go","lineNumber":102,"sourceCode":"\t\t\texpected = maxLargeObjectMessageLength\n\t\t}\n\n\t\tvar n int\n\t\terr := o.tx.QueryRow(o.ctx, \"select lowrite($1, $2)\", o.fd, p[nTotal:nTotal+expected]).Scan(&n)\n\t\tif err != nil {\n\t\t\treturn nTotal, err\n\t\t}\n\n\t\tif n < 0 {\n\t\t\treturn nTotal, errors.New(\"failed to write to large object\")\n\t\t}\n\n\t\tnTotal += n\n\n\t\tif n < expected {\n\t\t\treturn nTotal, errors.New(\"short write to large object\")\n\t\t} else if n > expected {\n\t\t\treturn nTotal, errors.New(\"invalid write to large object\")\n\t\t}\n\t}\n\n\treturn nTotal, nil\n}\n\n// Read reads up to len(p) bytes into p returning the number of bytes read.\nfunc (o *LargeObject) Read(p []byte) (int, error) {\n\tnTotal := 0\n\tfor {\n\t\texpected := len(p) - nTotal\n\t\tif expected == 0 {\n\t\t\tbreak\n\t\t} else if expected > maxLargeObjectMessageLength {\n\t\t\texpected = maxLargeObjectMessageLength\n\t\t}\n\n\t\tres := pgtype.PreallocBytes(p[nTotal:])","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/jackc/pgx/blob/ec1a0befd22592cffffdeeb0a50311b506372f4c/large_objects.go#L84-L120","documentation":"Returned by LargeObject.Write when lowrite reports a count strictly greater than the bytes requested (large_objects.go:101-102). This is logically impossible for a correct server — lowrite cannot write more bytes than were supplied. Its presence indicates a server bug, a corrupted response, or a protocol/codec desync where the scanned int does not represent the real byte count.","triggerScenarios":"The int32 scanned from lowrite exceeds the supplied chunk size, tripping the n > expected branch. Reachable only via server/protocol misbehavior.","commonSituations":"A buggy or experimental PostgreSQL extension overriding lowrite; protocol-level corruption desynchronizing the result reader; a custom type codec mis-decoding the lowrite return value; extremely rare server-side fault.","solutions":["Capture the exact n and expected values; this is almost always a server/extension bug worth reporting upstream.","Confirm no custom codec is intercepting the int32 return of lowrite.","Restart the connection / try a different PostgreSQL version to rule out a transient server fault.","File an issue against pgx only after ruling out server/extension causes; include server version and the failing payload size."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if _, err := lo.Write(p); err != nil {\n    if err.Error() == \"invalid write to large object\" {\n        // impossible-by-construction; treat as fatal protocol error\n        // reconnect or abort transaction, file a bug report\n    }\n    return err\n}","preventionTips":["Treat 'invalid write' as a server/protocol fault — reconnect and retry once.","Confirm no custom codec is mangling the lowrite int32 return.","Report upstream with server version and payload size if reproducible."],"tags":["large-objects","write","protocol-error","unreachable-guard"],"analyzedSha":"ec1a0befd22592cffffdeeb0a50311b506372f4c","analyzedAt":"2026-08-04T22:52:11.263Z","schemaVersion":2}