{"record":{"id":"5019b1da0085968a","repo":"Tencent/WeKnora","slug":"grpc-readstream-failed-w","errorCode":null,"errorMessage":"gRPC ReadStream failed: %w","messagePattern":"gRPC ReadStream failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/infrastructure/docparser/grpc_parser.go","lineNumber":157,"sourceCode":"\t\t// the gRPC message-size limit, which is exactly what streaming avoids).\n\t\tif status.Code(err) == codes.Unimplemented {\n\t\t\tlogger.Warnf(ctx, \"docreader ReadStream unimplemented, falling back to unary Read: %v\", err)\n\t\t\treturn p.readUnary(ctx, client, protoReq)\n\t\t}\n\t\treturn nil, err\n\t}\n\treturn result, nil\n}\n\n// readStream consumes the server-streaming ReadStream RPC: one meta frame\n// followed by one frame per image. Errors are returned verbatim so the caller\n// can inspect the gRPC status code (e.g. Unimplemented) for fallback.\nfunc (p *GRPCDocumentReader) readStream(\n\tctx context.Context, client proto.DocReaderClient, protoReq *proto.ReadRequest,\n) (*types.ReadResult, error) {\n\tstream, err := client.ReadStream(ctx, protoReq)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"gRPC ReadStream failed: %w\", err)\n\t}\n\n\tresult := &types.ReadResult{}\n\tgotMeta := false\n\tfor {\n\t\tframe, recvErr := stream.Recv()\n\t\tif recvErr == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif recvErr != nil {\n\t\t\treturn nil, fmt.Errorf(\"gRPC ReadStream recv failed: %w\", recvErr)\n\t\t}\n\n\t\tif meta := frame.GetMeta(); meta != nil {\n\t\t\tgotMeta = true\n\t\t\tresult.MarkdownContent = meta.GetMarkdownContent()\n\t\t\tresult.ImageDirPath = meta.GetImageDirPath()\n\t\t\tresult.Metadata = meta.GetMetadata()","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/infrastructure/docparser/grpc_parser.go#L139-L175","documentation":"Opening the server-streaming ReadStream RPC on the docreader failed in readStream. Callers may inspect the gRPC status: Unimplemented triggers a fallback to unary Read before this error path is taken for other codes.","triggerScenarios":"Thrown at internal/infrastructure/docparser/grpc_parser.go:157 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check docreader server health and logs","Inspect the wrapped gRPC status code for the root cause","Retry if the status indicates unavailability"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}