From 8d0356e3725b193c24953f425057eb5f25f357ae Mon Sep 17 00:00:00 2001 From: Tasnim Kabir Sadik Date: Sat, 11 Apr 2026 23:54:23 +0600 Subject: [PATCH 1/2] fix: stop overwriting agent gRPC errors with CodeInternal Removed the `connect.NewError(connect.CodeInternal, ...)` wrapper in the Server's MakeDir proxy handler. Previously, this wrapper was catching specific agent errors (like CodeAlreadyExists) and casting them into generic Code 13 (Internal) errors, stripping the gRPC metadata. This change allows the control-plane to act as a transparent pipeline, ensuring the API gateway can properly interpret and route specific filesystem failures. --- internal/hostagent/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/hostagent/server.go b/internal/hostagent/server.go index 0a86cf6..fad0d40 100644 --- a/internal/hostagent/server.go +++ b/internal/hostagent/server.go @@ -290,7 +290,7 @@ func (s *Server) MakeDir( resp, err := client.MakeDir(ctx, msg.Path) if err != nil { - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("make dir: %w", err)) + return nil, fmt.Errorf("make dir: %w", err) } return connect.NewResponse(&pb.MakeDirResponse{ From f5a9a1209f7ad6b1554a116fd009d4eca1fff05f Mon Sep 17 00:00:00 2001 From: Tasnim Kabir Sadik Date: Sat, 11 Apr 2026 23:54:48 +0600 Subject: [PATCH 2/2] fix: map CodeAlreadyExists to HTTP 409 Conflict Updated the `agentErrToHTTP` switch statement to explicitly catch `connect.CodeAlreadyExists` (as well as `connect.CodeFailedPrecondition`) and return `http.StatusConflict` (409) instead of falling through to the default 502 Bad Gateway. --- internal/api/middleware.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/api/middleware.go b/internal/api/middleware.go index cf9108f..95d2175 100644 --- a/internal/api/middleware.go +++ b/internal/api/middleware.go @@ -50,8 +50,12 @@ func agentErrToHTTP(err error) (int, string, string) { return http.StatusNotFound, "not_found", err.Error() case connect.CodeInvalidArgument: return http.StatusBadRequest, "invalid_request", err.Error() - case connect.CodeFailedPrecondition: + case connect.CodeFailedPrecondition, connect.CodeAlreadyExists: return http.StatusConflict, "conflict", err.Error() + case connect.CodePermissionDenied: + return http.StatusForbidden, "forbidden", err.Error() + case connect.CodeUnimplemented: + return http.StatusNotImplemented, "agent_error", err.Error() default: return http.StatusBadGateway, "agent_error", err.Error() }