Skip to content

fix(api): build secrets gRPC service config as JSON literal (fixes rls.proto double-registration panic) - #3800

Open
AdaAibaby wants to merge 1 commit into
e2b-dev:mainfrom
AdaAibaby:fix/grpc-service-config-literal-json
Open

AdaAibaby wants to merge 1 commit into
e2b-dev:mainfrom
AdaAibaby:fix/grpc-service-config-literal-json

Conversation

@AdaAibaby

@AdaAibaby AdaAibaby commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Any binary that links packages/api/internal/handlers (including its test binary) panics at init:

panic: proto: file "grpc/lookup/v1/rls.proto" is already registered
	previously from: "buf.build/gen/go/grpc/grpc/protocolbuffers/go/grpc/lookup/v1"
	currently from:  "google.golang.org/grpc/internal/proto/grpc_lookup_v1"

Minimal repro / root cause

  • handlers/secrets.go imported buf.build/gen/go/grpc/grpc/protocolbuffers/go/grpc/service_config purely to build the default gRPC service-config JSON.
  • That service_config proto transitively imports grpc/lookup/v1/rls.proto (RLS load-balancing config).
  • google.golang.org/grpc (>= v1.84) ships its own internal copy of that descriptor at google.golang.org/grpc/internal/proto/grpc_lookup_v1.
  • Both register the same file path grpc/lookup/v1/rls.proto → protoregistry panics on the second init.

go mod why shows the chain is pulled in only via secrets.go → service_config → lookup/v1; the main module does not otherwise need it.

Reproduce: go test ./packages/api/internal/handlers/ (panics at init before any test runs).

Fix

Build the service config as a string literal — byte-for-byte what protojson previously emitted:

{"loadBalancingConfig":[{"round_robin":{}}], "healthCheckConfig":{"serviceName":"..."}}

and drop the buf.build service_config import (plus the now-unused protojson/wrapperspb). gRPC client behavior is unchanged (round-robin LB + health-check readiness service); the handlers test binary no longer panics at init.

Why separate

This is an independent, pre-existing bug (present on main, unrelated to the template-artifact cleanup work). The template-artifact PRs (#3797/#3798) need this merged for their handlers-package unit tests to run in CI; their DB-backed tests pass independently.

Test

go build ./... clean; go test ./packages/api/internal/handlers/ no longer panics at init.

/cc @ryan-sana Looking forward to your code review.

…importing proto

secrets.go built the default gRPC service config via the buf.build
service_config protobuf. That proto transitively imports
grpc/lookup/v1/rls.proto, whose descriptor is registered a second time by
grpc-go's own internal grpc_lookup_v1 package, so any binary (incl. the
packages/api/internal/handlers test binary) panics at init with
"rls.proto is already registered".

Build the service config as a string literal instead — byte-for-byte what
protojson previously emitted for round_robin + the health-check service name —
and drop the buf.build service_config / protojson / wrapperspb imports. Client
behavior is unchanged; the handlers test binary no longer panics at init.
@AdaAibaby
AdaAibaby force-pushed the fix/grpc-service-config-literal-json branch from 6c278c9 to ccd3350 Compare November 9, 2026 03:33

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant