Tencent/WeKnora · error

MinerU Cloud state=done but no markdown/content or full_zip_

Error message

MinerU Cloud state=done but no markdown/content or full_zip_url

What it means

The MinerU Cloud batch item reported state=done, but the parsed item contains no inline markdown/content text and no full_zip_url to download results from, so extractDoneResult has nothing to return (mineru_cloud_converter.go:339). This indicates an inconsistent server response: the task claims completion but carries no result payload. The library treats this as fatal for the item.

Source

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

			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))
		return text, nil, nil
	}

	if item.FullZipURL == "" {
		return "", nil, fmt.Errorf("MinerU Cloud state=done but no markdown/content or full_zip_url")
	}

	md, imageRefs, err := downloadAndExtractZip(item.FullZipURL)
	if err != nil {
		return "", nil, fmt.Errorf("extract zip: %w", err)
	}

	logger.Infof(context.Background(), "[MinerUCloud] parsed (zip), markdown=%d chars, images=%d", len(md), len(imageRefs))
	return md, imageRefs, nil
}

// --- ZIP handling ---

var imgRefPattern = regexp.MustCompile(`!\[[^\]]*\]\(([^)]+)\)`)

func downloadAndExtractZip(zipURL string) (string, []types.ImageRef, error) {
	if err := utils.ValidateURLForSSRF(zipURL); err != nil {
		return "", nil, fmt.Errorf("zip URL blocked by SSRF check: %v", err)

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Dump the raw extractResultItem JSON to confirm whether full_zip_url/markdown/content were present but not unmarshaled (field-name mismatch).
  2. Update the extractResultItem struct tags to match the current API field names.
  3. Re-submit the document — a done state with no payload usually means the server-side conversion actually failed.
  4. Check result retention: if the batch was created long ago, results may have been purged; poll promptly after completion.

Example fix

// before
FullZipURL string `json:"fullZipUrl"`
// after — correct the json tag to match the API
FullZipURL string `json:"full_zip_url"`
Markdown   string `json:"markdown"`
Defensive patterns

Strategy: validation

Validate before calling

func isUsableDoneItem(item extractResultItem) bool {
    return item.State == "done" &&
        (item.Markdown != "" || item.Content != nil || item.FullZipURL != "")
}

Type guard

func hasResultPayload(item extractResultItem) bool {
    return item.FullZipURL != "" || item.Markdown != ""
}

Try / catch

md, images, err := pollBatchResult(ctx, batchID)
if err != nil {
    if strings.Contains(err.Error(), "state=done but no markdown/content or full_zip_url") {
        // server said done but delivered nothing: re-submit
        return resubmitBatch(ctx, doc)
    }
    return err
}

Prevention

When it happens

Trigger: pollBatchResult -> extractDoneResult receives an item with state "done" where both the inline markdown/content fields are empty and item.FullZipURL == "" — a done item lacking any result payload.

Common situations: MinerU Cloud partially completed the task (processing error internally marked done); API change removing/renaming the markdown/content/full_zip_url fields so they no longer unmarshal; result retention expiry zeroing out payloads while state stays 'done'.

Related errors


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