{"record":{"id":"2aa363a2568c1632","repo":"apache/beam","slug":"failed-to-find-worker-id-in-metadata-v","errorCode":null,"errorMessage":"failed to find worker id in metadata %v","messagePattern":"failed to find worker id in metadata (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/util/grpcx/metadata.go","lineNumber":36,"sourceCode":"\nimport (\n\t\"context\"\n\n\t\"github.com/apache/beam/sdks/v2/go/pkg/beam/internal/errors\"\n\t\"google.golang.org/grpc/metadata\"\n)\n\nconst idKey = \"worker_id\"\n\n// ReadWorkerID reads the worker ID from an incoming gRPC request context.\nfunc ReadWorkerID(ctx context.Context) (string, error) {\n\tmd, ok := metadata.FromIncomingContext(ctx)\n\tif !ok {\n\t\treturn \"\", errors.New(\"failed to read metadata from context\")\n\t}\n\tid, ok := md[idKey]\n\tif !ok || len(id) < 1 {\n\t\treturn \"\", errors.Errorf(\"failed to find worker id in metadata %v\", md)\n\t}\n\tif len(id) > 1 {\n\t\treturn \"\", errors.Errorf(\"multiple worker ids in metadata: %v\", id)\n\t}\n\treturn id[0], nil\n}\n\n// WriteWorkerID write the worker ID to an outgoing gRPC request context. It\n// merges the information with any existing gRPC metadata.\nfunc WriteWorkerID(ctx context.Context, id string) context.Context {\n\tmd := metadata.New(map[string]string{\n\t\tidKey: id,\n\t})\n\tif old, ok := metadata.FromOutgoingContext(ctx); ok {\n\t\tmd = metadata.Join(md, old)\n\t}\n\treturn metadata.NewOutgoingContext(ctx, md)\n}","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/util/grpcx/metadata.go#L18-L54","documentation":"grpcx.ReadWorkerID finds the worker ID under the metadata key idKey. This error is returned when the incoming context HAS metadata but no entry under that key (or an empty slice), and includes the full metadata map for debugging. It distinguishes 'no metadata at all' (5378) from 'metadata present but worker id key missing'.","triggerScenarios":"A gRPC request reaches ReadWorkerID with metadata that lacks the worker-id key — the client set other metadata or used the wrong key name, or the id slice is empty.","commonSituations":"Custom Beam worker clients using a metadata key name that doesn't match the server's idKey; partial metadata propagation through proxies/interceptors; version mismatch where the key naming convention changed.","solutions":["Set the worker id under the expected key (use grpcx.AddWorkerID so the key always matches)","Compare the keys printed in the error message with what the client sends","Ensure only one non-empty worker id value is present (avoids the related 'multiple worker ids' error)"],"exampleFix":"// before\nctx = metadata.AppendToOutgoingContext(ctx, \"id\", workerID) // wrong key\n// after\nctx = metadata.AppendToOutgoingContext(ctx, \"beam:worker:id:1\", workerID)","handlingStrategy":"validation","validationCode":"md, _ := metadata.FromIncomingContext(ctx)\nif len(md[idKey]) == 0 {\n\treturn errors.New(\"worker id key missing in metadata\")\n}","typeGuard":"func hasWorkerID(ctx context.Context) bool {\n\tmd, ok := metadata.FromIncomingContext(ctx)\n\treturn ok && len(md[idKey]) > 0\n}","tryCatchPattern":"id, err := grpcx.ReadWorkerID(ctx)\nif err != nil {\n\tif strings.Contains(err.Error(), \"failed to find worker id\") {\n\t\treturn status.Error(codes.InvalidArgument, \"worker id key missing; use grpcx.AddWorkerID\")\n\t}\n\treturn err\n}","preventionTips":["Use the library's AddWorkerID helper so key names always match","Log full metadata when debugging worker routing","Pin client and server to the same SDK version to avoid key-name drift"],"tags":["grpc","metadata","apache-beam"],"backgroundTag":"missing-required-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}