fish2018/pansou · error
%s
Error message
%s
What it means
The miosou plugin records an upstream streaming error event. When an SSE event named "error" arrives, it tries to parse the event data as JSON and use its "message" field; if that fails, it uses the raw event text. This is a wrapped relay of whatever error message the upstream AI/streaming service sent, not a bug in the plugin itself.
Solutions
- Read the wrapped message text to see the actual upstream error and fix the root cause (key, quota, model name).
- Verify the upstream account credentials and quota for the miosou provider.
- Retry the request; transient upstream errors often resolve on retry.
- Check whether the upstream endpoint changed its SSE error payload format.
Example fix
// before
streamErr = fmt.Errorf("%s", payload.Message)
// after
if payload.Message == "" {
payload.Message = "unknown upstream stream error"
}
streamErr = fmt.Errorf("miosou upstream: %s", payload.Message) Defensive patterns
Strategy: try-catch
Try / catch
results, err := pluginSearch(ctx, query)
if err != nil {
log.Printf("miosou upstream error: %v", err)
// fall back to another provider or surface message to user
return fallbackProvider(ctx, query)
} Prevention
- Keep upstream API keys and quotas valid to avoid provider-side error events.
- Monitor upstream provider status pages.
- Implement provider fallback for streaming searches.
When it happens
Trigger: Upstream stream emits an SSE event with event=="error"; occurs on upstream auth failures, model errors, quota exhaustion, or mid-stream provider outages.
Common situations: Expired or invalid upstream API key, upstream rate limiting, provider returning an error mid-generation, or a proxy/gateway returning HTML that is passed through as raw text.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/00bcd6bb72a1b96e.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/miosou/miosou.go:340
var data strings.Builder
var streamErr error
flush := func() {
if data.Len() == 0 {
return
}
if event == "snapshot" || event == "" {
var snapshot searchSnapshot
if json.Unmarshal([]byte(data.String()), &snapshot) == nil {
for cloud, items := range snapshot.MergedByType {
groups[cloud] = mergeItems(groups[cloud], items)
}
}
} else if event == "error" {
var payload struct {
Message string `json:"message"`
}
if json.Unmarshal([]byte(data.String()), &payload) == nil && payload.Message != "" {
streamErr = fmt.Errorf("%s", payload.Message)
} else {
streamErr = fmt.Errorf("%s", strings.TrimSpace(data.String()))
}
}
event = ""
data.Reset()
}
for scanner.Scan() {
line := scanner.Text()
if line == "" {
flush()
continue
}
if strings.HasPrefix(line, "event:") {
event = strings.TrimSpace(strings.TrimPrefix(line, "event:"))
} else if strings.HasPrefix(line, "data:") {
if data.Len() > 0 {
data.WriteByte('\n')View on GitHub (pinned to beaa561337)