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

  1. Read the wrapped message text to see the actual upstream error and fix the root cause (key, quota, model name).
  2. Verify the upstream account credentials and quota for the miosou provider.
  3. Retry the request; transient upstream errors often resolve on retry.
  4. 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

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)