fish2018/pansou · error
[ ] 接口配置缺少必要字段
Error message
[%s] 接口配置缺少必要字段
What it means
The bootstrap config decoded and unmarshalled successfully into apiConfig, but its contents failed sanity validation: URLVersion or UserID is empty, Start is negative, End <= Start, or End > 24. fetchConfig refuses to continue with a config that cannot produce valid search URLs or paging windows.
Solutions
- Dump the decoded JSON and compare its field names/types against the apiConfig struct tags
- Update the apiConfig struct (json tags) to match the current server schema
- Confirm the account/API version still provides UserID and URLVersion
- Add a log of the raw config to catch silent schema drift early
Example fix
// before
type apiConfig struct {
URLVersion string `json:"url_version"`
}
// after
type apiConfig struct {
URLVersion string `json:"urlVersion"`
UserID string `json:"userId"`
Start int `json:"start"`
End int `json:"end"`
} Defensive patterns
Strategy: validation
Validate before calling
func validConfig(c apiConfig) bool {
return c.URLVersion != "" && c.UserID != "" &&
c.Start >= 0 && c.End > c.Start && c.End <= 24
} Type guard
func (c apiConfig) OK() bool {
return c.URLVersion != "" && c.UserID != "" &&
c.Start >= 0 && c.End > c.Start && c.End <= 24
} Try / catch
cfg, err := p.fetchConfig(ctx, client)
if err != nil {
if strings.Contains(err.Error(), "缺少必要字段") {
log.Printf("yingso config schema drift detected: %+v", cfg)
}
return err
} Prevention
- Compare decoded JSON keys against apiConfig json tags after any API update
- Log the raw decoded config on validation failure to spot renamed fields
- Write a golden-file test unmarshalling a live /test payload snapshot
- Fail fast at startup so schema drift is caught before serving searches
When it happens
Trigger: After unmarshalling, config.URLVersion == "" || config.UserID == "" || config.Start < 0 || config.End <= config.Start || config.End > 24 in fetchConfig.
Common situations: The server-side config schema changed (fields renamed, moved, or removed) so they unmarshal as zero values; the XOR decode produced valid JSON of the wrong shape; the server returns partial config during maintenance or for deprecated API versions.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/4c5fe1cc884d6797.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/yingso/yingso.go:205
return plugin.FilterResultsByKeyword(results, keyword), nil
}
func (p *YingsoPlugin) fetchConfig(ctx context.Context, client *http.Client) (apiConfig, error) {
var response apiEnvelope[string]
if err := p.requestJSON(ctx, client, http.MethodGet, p.apiBaseURL+"/test", nil, &response); err != nil {
return apiConfig{}, fmt.Errorf("[%s] 获取接口配置失败: %w", p.Name(), err)
}
if response.Code != http.StatusOK || response.Data == "" {
return apiConfig{}, fmt.Errorf("[%s] 接口配置异常: code=%d msg=%s", p.Name(), response.Code, response.Msg)
}
decoded := xorUTF16(response.Data, bootstrapKey)
var config apiConfig
if err := jsonutil.UnmarshalString(decoded, &config); err != nil {
return apiConfig{}, fmt.Errorf("[%s] 解析接口配置失败: %w", p.Name(), err)
}
if config.URLVersion == "" || config.UserID == "" || config.Start < 0 || config.End <= config.Start || config.End > 24 {
return apiConfig{}, fmt.Errorf("[%s] 接口配置缺少必要字段", p.Name())
}
return config, nil
}
func (p *YingsoPlugin) search(ctx context.Context, client *http.Client, config apiConfig, keyword string) ([]searchItem, error) {
payload := searchPayload{
PageSize: pageSize,
PageNum: 1,
Title: keyword,
Root: 0,
Category: "all",
UserID: config.UserID,
}
encrypted, err := encryptPayload(payload, config)
if err != nil {
return nil, fmt.Errorf("[%s] 生成搜索参数失败: %w", p.Name(), err)
}
View on GitHub (pinned to beaa561337)