QuantumNous/new-api · critical
implement me
Error message
implement me
What it means
The xunfei (iFlytek Spark) Adaptor's ConvertClaudeRequest contains a bare panic("implement me") left from an IDE-generated method stub. If a relay request in Claude format is routed to an xunfei channel, this panic crashes the Go process (or is caught by Gin's recovery middleware, aborting the request) instead of returning a clean 'not implemented' error like the sibling methods.
Source
Thrown at relay/channel/xunfei/adaptor.go:28
relaycommon "github.com/QuantumNous/new-api/relay/common"
"github.com/QuantumNous/new-api/relaykit/dto"
"github.com/QuantumNous/new-api/relaykit/types"
"github.com/gin-gonic/gin"
)
type Adaptor struct {
request *dto.GeneralOpenAIRequest
}
func (a *Adaptor) ConvertGeminiRequest(*gin.Context, *relaycommon.RelayInfo, *dto.GeminiChatRequest) (any, error) {
//TODO implement me
return nil, errors.New("not implemented")
}
func (a *Adaptor) ConvertClaudeRequest(*gin.Context, *relaycommon.RelayInfo, *dto.ClaudeRequest) (any, error) {
//TODO implement me
panic("implement me")
}
func (a *Adaptor) ConvertAudioRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.AudioRequest) (io.Reader, error) {
//TODO implement me
return nil, errors.New("not implemented")
}
func (a *Adaptor) ConvertImageRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.ImageRequest) (any, error) {
//TODO implement me
return nil, errors.New("not implemented")
}
func (a *Adaptor) Init(info *relaycommon.RelayInfo) {
}
func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
return "", nil
}View on GitHub (pinned to e2c7aa7b10)
Solutions
- Replace panic with the same error return used by the other stubs: return nil, errors.New("not implemented").
- Prevent routing: do not put xunfei channels in groups that will serve Claude-format requests; keep model lists disjoint.
- Upgrade once the adaptor implements Claude conversion or the relay returns 400 for unsupported format/channel pairs before dispatch.
- Ensure Gin recovery middleware is active so a residual panic cannot take down the whole gateway.
Example fix
// before
func (a *Adaptor) ConvertClaudeRequest(*gin.Context, *relaycommon.RelayInfo, *dto.ClaudeRequest) (any, error) {
//TODO implement me
panic("implement me")
}
// after
func (a *Adaptor) ConvertClaudeRequest(*gin.Context, *relaycommon.RelayInfo, *dto.ClaudeRequest) (any, error) {
return nil, errors.New("claude format is not supported by the xunfei channel")
} Defensive patterns
Strategy: fallback
Prevention
- Grep relay/channel/*/adaptor.go for panic( and replace every stub panic with error returns before release.
- Enforce format/channel compatibility at routing time: reject Claude-format requests aimed at channels that do not implement ConvertClaudeRequest.
- Keep Gin recovery middleware on all relay routes so a stray panic cannot kill the gateway.
- Add a compile-time or test-time checklist that every Adaptor interface method returns (nil, err) rather than panicking.
When it happens
Trigger: A client calls /v1/Messages (Claude-format endpoint) and the model resolves to a channel of type xunfei; or a Claude-format native request is load-balanced onto an xunfei channel. The relay dispatches to ConvertClaudeRequest and the process panics.
Common situations: Mixing Claude-format models into a channel group that contains xunfei channels; model-name routing that unexpectedly matches an xunfei channel; adding xunfei channels to a group that serves /v1/Messages clients.
Related errors
AI-assisted analysis of QuantumNous/new-api@e2c7aa7b10 (2026-08-15).
Data as JSON: /api/errors/af85d5c9836c1446.
Report an issue: GitHub.