Tencent/WeKnora · error

decode extract_result array: %w

Error message

decode extract_result array: %w

What it means

The extract_result field inside the poll response is a JSON string whose first character is '[', so the library tries to decode it as an array of extractResultItem; that array decode failed (mineru_cloud_converter.go:316). extract_result is a doubly-encoded JSON value, and the MinerU Cloud payload inside it did not match the expected []extractResultItem schema.

Source

Thrown at internal/infrastructure/docparser/mineru_cloud_converter.go:316

	// Dump the raw extract_result JSON for debugging
	rawExtract := string(pollResp.Data.ExtractResult)
	if len(rawExtract) > 4000 {
		logger.Infof(context.Background(), "[MinerUCloud] Raw extract_result (truncated to 4000 chars): %s ...", rawExtract[:4000])
	} else {
		logger.Infof(context.Background(), "[MinerUCloud] Raw extract_result: %s", rawExtract)
	}

	// Pretty-print the structure to reveal all available fields
	var rawObj interface{}
	if err := json.Unmarshal(pollResp.Data.ExtractResult, &rawObj); err == nil {
		logResponseStructure("MinerUCloud", rawObj, "extract_result")
	}

	// The extract_result can be either a single object or an array
	var items []extractResultItem
	if pollResp.Data.ExtractResult[0] == '[' {
		if err := json.Unmarshal(pollResp.Data.ExtractResult, &items); err != nil {
			return nil, fmt.Errorf("decode extract_result array: %w", err)
		}
	} else {
		var single extractResultItem
		if err := json.Unmarshal(pollResp.Data.ExtractResult, &single); err != nil {
			return nil, fmt.Errorf("decode extract_result object: %w", err)
		}
		items = []extractResultItem{single}
	}

	return items, nil
}

// extractDoneResult extracts markdown and images from a completed batch item.
// Prefers inline markdown/content fields; falls back to downloading full_zip_url.
func (c *MinerUCloudReader) extractDoneResult(_ context.Context, item *extractResultItem) (string, []types.ImageRef, error) {
	text := firstNonEmpty(item.Markdown, item.Content, item.Text)
	if text != "" {
		logger.Infof(context.Background(), "[MinerUCloud] parsed (inline), length=%d", len(text))

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Dump the raw extract_result string on failure to compare against the extractResultItem struct (full_zip_url, markdown/content fields).
  2. Update the extractResultItem struct to match the current MinerU Cloud schema (check for new/renamed fields).
  3. Ensure array elements are objects, not strings or nulls; handle null entries defensively.
  4. Pin/verify the MinerU Cloud API version if the contract changed unexpectedly.

Example fix

// before
type extractResultItem struct {
    State      string `json:"state"`
    FullZipURL string `json:"full_zip_url"`
}
// after — tolerate null entries / new fields
type extractResultItem struct {
    State      string `json:"state"`
    FullZipURL string `json:"full_zip_url"`
    Markdown   string `json:"markdown"`
    Content    json.RawMessage `json:"content"`
}
Defensive patterns

Strategy: type-guard

Validate before calling

var raw any
if err := json.Unmarshal(pollResp.Data.ExtractResult, &raw); err != nil {
    return fmt.Errorf("extract_result is not valid JSON: %w", err)
}
if _, ok := raw.([]any); !ok {
    return errors.New("extract_result is not a JSON array")
}

Type guard

func isExtractResultArray(raw json.RawMessage) bool {
    var arr []json.RawMessage
    return json.Unmarshal(raw, &arr) == nil
}

Try / catch

items, err := pollBatchResult(ctx, batchID)
if err != nil {
    if strings.Contains(err.Error(), "decode extract_result array") {
        // schema drift: log raw payload and surface a contract error
        return fmt.Errorf("mineru schema mismatch: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: fetchBatchStatus receives extract_result starting with '[' but its contents don't match []extractResultItem — e.g. an array of plain strings, an array with null elements, or an API change adding/removing required fields.

Common situations: MinerU Cloud API version change altering the extract_result item schema; a partial/failure entry serialized differently from successful entries; hand-rolled mock servers in tests returning the wrong shape.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/3fc45e5129f12672. Report an issue: GitHub.