fish2018/pansou · warning
detail status=
Error message
detail status=%d
What it means
fetchDiscussionLinks fetches a single discussion detail page via p.scraper.Get and returns this compact error when the HTTP status is not 200. The caller (detail worker goroutine) logs a warning and skips that discussion's links rather than failing the whole search.
Solutions
- Check the status code in the error — 404 means the discussion is gone and should be skipped
- Slow down detail requests or lower detailWorkers to avoid 429
- Pass Cloudflare challenges via cloudscraper updates or proxies for 403/503
- Treat it as non-fatal: the search already degrades gracefully by dropping that result
Defensive patterns
Strategy: fallback
Try / catch
if err != nil {
if strings.Contains(err.Error(), "detail status=404") {
// discussion deleted: drop result silently
} else if strings.Contains(err.Error(), "detail status=429") {
// rate limited: back off detail workers
}
} Prevention
- Keep detailWorkers low to avoid tripping rate limits
- Treat per-item detail failures as non-fatal (the plugin already does)
- Rotate proxies/cookies when 403s cluster
When it happens
Trigger: GET of /api/discussions/{id} returns 403 (Cloudflare block), 404 (discussion deleted), or 429/5xx while resolving download links for one search result.
Common situations: Individual discussion removed since indexing; per-IP rate limiting on detail requests; Cloudflare challenge triggered by bursts of detail fetches (4 concurrent workers).
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/c4811af908b2176b.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/panzun/panzun.go:281
for _, item := range ordered {
if item.ok {
results = append(results, item.result)
}
}
return results, nil
}
func (p *PanzunPlugin) fetchDiscussionLinks(client *http.Client, discussionID string) ([]model.Link, string, []string, time.Time, error) {
detailURL := fmt.Sprintf("%s/discussions/%s", apiBase, discussionID)
resp, err := p.scraper.Get(detailURL)
if err != nil {
return nil, "", nil, time.Time{}, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, "", nil, time.Time{}, fmt.Errorf("detail status=%d", resp.StatusCode)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, "", nil, time.Time{}, err
}
var detailResp struct {
Data Discussion `json:"data"`
Included []IncludedResource `json:"included"`
}
if err := jsonutil.Unmarshal(body, &detailResp); err != nil {
return nil, "", nil, time.Time{}, err
}
includedMap := buildIncludedMap(detailResp.Included)
rel := detailResp.Data.Relationships
View on GitHub (pinned to beaa561337)