CompressionFilter’s IdentityHandler.writeMessage calls Buffer-only .copy() on caller-provided message
I maintainer di solito rispondono entro 2 giorni
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 82/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Tranquilla
- Stack tecnologico
- node.js, typescript
Direzione di ricerca
Inizia in packages/grpc-js/src/compression-filter.ts, in IdentityHandler.writeMessage, quindi riproduci il fallimento con un requestSerialize personalizzato che restituisce un Uint8Array. Verifica che lo stesso percorso accetti messaggi sia Uint8Array sia Buffer senza il TypeError e produca un risultato o uno stato RPC significativo.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Problem description
CompressionFilter's IdentityHandler.writeMessage (packages/grpc-js/src/compression-filter.ts) calls message.copy(output, 5), which is a Buffer-only method:
async writeMessage(message, compress) {
const output = Buffer.allocUnsafe(message.length + 5);
output.writeUInt8(0, 0);
output.writeUInt32BE(message.length, 1);
message.copy(output, 5); // ← Buffer-only
return output;
}
Uint8Array.prototype.copy is undefined. If the caller-provided request serializer produces a Uint8Array rather than a Buffer, this throws TypeError: message.copy is not a function. The thrown error then propagates as a code: undefined, details: undefined, empty-Metadata gRPC status (the empty-status side is tracked separately: https://github.com/grpc/grpc-node/issues/3051).
Uint8Array request serializers are reachable in practice via protobufjs, which falls back to Uint8Array-returning Writer.alloc whenever protobufjs.util.Buffer is unset. One concrete trigger is the @protobufjs/[email protected] regression — see protobufjs/protobuf.js#2214 — where bundlers (Turbopack, certain webpack configurations) statically rewrite the new dynamic require(name) to throw MODULE_NOT_FOUND, leaving util.Buffer = null in any bundled server build.
Reproduction steps
In a Next.js 16 application with output: "standalone" (Turbopack):
- Add
@google-cloud/[email protected]and use it from a Server Component (any call works:collection(...).get(),doc(...).get(), etc.). - Ensure
@protobufjs/inquireresolves to1.1.1(the default with[email protected]+). next buildand run the standalone output. Trigger any Firestore call.
Expected: the call succeeds or fails with a meaningful status.
Actual: the call's callback receives Error: undefined undefined: undefined with { code: undefined, details: undefined, metadata: Metadata { internalRepr: Map(0) {}, options: {} } }. Running with GRPC_TRACE=all GRPC_VERBOSITY=DEBUG shows cancelWithStatus code: undefined details: "undefined" firing within 1 ms of write() called with message of length N.
Independent of protobufjs, the same path is reachable by registering a custom method whose requestSerialize returns new Uint8Array([...]) and calling client.makeUnaryRequest(...).
Environment
- OS: macOS 15.6 arm64 (local repro); Linux amd64 (Google Cloud Run production)
- Node: v24
- Node installation: project
engines.node = "24", npm 11 - Package:
@grpc/[email protected] - Adjacent:
[email protected],@google-cloud/[email protected],@grpc/[email protected], Next.js 16.2.6 with Turbopack
Additional context
Suggested fix: output.set(message, 5) in place of message.copy(output, 5). Buffer extends Uint8Array and both expose .set, so the call works for either input.
Impact in our deployment: a Dependabot bump to [email protected] (which pulls @protobufjs/[email protected] transitively) caused this TypeError on every Firestore call. Under google-gax retry the undefined code is treated as retryable, so the call retries for the gax budget before bubbling up. For server-streaming RPCs under additional SDK-level retry (Firestore's QueryUtil._stream), every request hangs for ~45 s and then 500s. We hit a production outage before identifying the underlying chain.
- Lingua principale
- TypeScript
- Stelle
- 4.8k
- Fork
- 716
- Merge medio
- 1g 18h
- PR unite (30g)
- 17
Preparare l'ambiente
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di grpc/grpc-node
-
package: @grpc/grpc-js
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
grpc/grpc-node#2993 · 3 commenti · 4 reazioni ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 65/100
grpc/grpc-node#3091 · 1 reazione ·
I maintainer di solito rispondono entro 2 giorni
-
feature request
Difficoltà 3/5 1-2 giorni Idoneità per principianti 68/100
grpc/grpc-node#3077 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 76/100
grpc/grpc-node#3068 · 2 commenti · 1 reazione ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 55/100
grpc/grpc-node#3062 · 2 commenti · 1 reazione ·
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di grpc/grpc-node
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
microsoft/vscode-livepreview#876 ·
I maintainer di solito rispondono entro 1 giorno
-
needs-triage
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
JustJarethB/invoicer#54 ·
-
ICP 1.2.0 shows a scheduled task's interval in milliseconds under the label "Interval (In seconds)"ApertaNeeds Triage Type/Bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
wso2/product-integrator#2585 ·
I maintainer di solito rispondono entro 1 giorno
-
Add: Telemundo West sdApertacheck:passed streams:add
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
I maintainer di solito rispondono entro 1 giorno
-
design
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
MTES-MCT/monitor-field#119 ·
I maintainer di solito rispondono entro 1 giorno