From 0ca36eeb3ce8ae4dd015ca6bdf1a0dce2c806800 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Sun, 4 Oct 2026 04:58:32 -0700 Subject: [PATCH] fix(actions): return 401 for unregistered runner (#39578) (#39585) Backport #39578 Signed-off-by: Alex Mitre Co-authored-by: Dr Alex Mitre Co-authored-by: Alex Mitre Co-authored-by: wxiaoguang --- routers/api/actions/runner/interceptor.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/routers/api/actions/runner/interceptor.go b/routers/api/actions/runner/interceptor.go index 8b79962c11d..e981deff303 100644 --- a/routers/api/actions/runner/interceptor.go +++ b/routers/api/actions/runner/interceptor.go @@ -27,6 +27,9 @@ const ( ) var withRunner = connect.WithInterceptors(connect.UnaryInterceptorFunc(func(unaryFunc connect.UnaryFunc) connect.UnaryFunc { + // A plain gRPC status.Error is treated as unknown by Connect and becomes HTTP 500 + // To respond an HTTP status code, use connect.Error instead + errUnregisteredRunner := connect.NewError(connect.CodeUnauthenticated, errors.New("unregistered runner")) return func(ctx context.Context, request connect.AnyRequest) (connect.AnyResponse, error) { methodName := getMethodName(request) if methodName == "Register" { @@ -38,12 +41,12 @@ var withRunner = connect.WithInterceptors(connect.UnaryInterceptorFunc(func(unar runner, err := actions_model.GetRunnerByUUID(ctx, uuid) if err != nil { if errors.Is(err, util.ErrNotExist) { - return nil, status.Error(codes.Unauthenticated, "unregistered runner") + return nil, errUnregisteredRunner } return nil, status.Error(codes.Internal, err.Error()) } if !util.CryptoConstTimeEqual(runner.TokenHash, auth_model.HashToken(token, runner.TokenSalt)) { - return nil, status.Error(codes.Unauthenticated, "unregistered runner") + return nil, errUnregisteredRunner } now := time.Now()