Wei-Shaw/sub2api · error

invalid_request_error

invalid_request_error

Error message

request body is required

What it means

Thrown by readGrokVoiceGatewayBody when the gin Context or its Request is nil (code=invalid_request_error). This is a defensive guard before any body read; in normal HTTP serving these are never nil, so encountering it means the handler was invoked programmatically or the request context was corrupted.

Source

Thrown at backend/internal/handler/grok_audio.go:313

			QuotaPlatform:      quotaPlatform,
			SessionID:          sessionID,
			ChannelUsageFields: clientRequestedUsageFields(c, service.ChannelMappingResult{}, model, result.UpstreamModel),
		}); err != nil {
			logger.L().With(
				zap.String("component", "handler.openai_gateway.grok_voice"),
				zap.Int64("user_id", apiKey.User.ID),
				zap.Int64("api_key_id", apiKey.ID),
				zap.Any("group_id", apiKey.GroupID),
				zap.String("endpoint", endpoint),
				zap.Int64("account_id", account.ID),
			).Error("grok_voice.record_usage_failed", zap.Error(err))
		}
	})
}

func readGrokVoiceGatewayBody(c *gin.Context) ([]byte, error) {
	if c == nil || c.Request == nil {
		return nil, errors.New("request body is required")
	}
	if c.Request.Body == nil {
		if c.Request.Method == http.MethodGet || c.Request.Method == http.MethodDelete {
			return nil, nil
		}
		return nil, errors.New("request body is required")
	}
	return io.ReadAll(c.Request.Body)
}

// extractGrokTTSInputText pulls the primary spoken text from a TTS JSON body.
func extractGrokTTSInputText(body []byte) string {
	if len(body) == 0 {
		return ""
	}
	var payload map[string]any
	if err := json.Unmarshal(body, &payload); err != nil {
		return ""

View on GitHub (pinned to 073e92d171)

Solutions

  1. If seen in tests, construct the handler input with gin.CreateTestContext and set c.Request = httptest.NewRequest(...)
  2. Audit custom middleware that wraps or replaces the context to ensure Request is never dropped

Example fix

// before
c := gin.CreateTestContext(t)
h.handleVoice(c) // c.Request == nil
// after
c := gin.CreateTestContext(t)
c.Request = httptest.NewRequest(http.MethodPost, "/v1/voice", strings.NewReader("{}"))
h.handleVoice(c)
Defensive patterns

Strategy: type-guard

Validate before calling

// Go: never invoke the handler without a request
if c == nil || c.Request == nil {
    return errors.New("request context is not initialized")
}

Type guard

// Go
type requestCarrier interface{ GetRequest() *http.Request }
func hasRequest(c any) bool {
    if g, ok := c.(*gin.Context); ok { return g != nil && g.Request != nil }
    return false
}

Prevention

When it happens

Trigger: Internal/test invocation of the Grok voice gateway handler with a nil *gin.Context, or a nil Request inside a constructed Context. Not reachable through a real HTTP request.

Common situations: Unit tests calling the handler directly without a request recorder; middleware or wrappers that pass a nil context in error paths.

Related errors


AI-assisted analysis of Wei-Shaw/sub2api@073e92d171 (2026-08-15). Data as JSON: /api/errors/15e72bd5f34b0213. Report an issue: GitHub.