Tencent/WeKnora · error

poll error code=%d msg=%s

Error message

poll error code=%d msg=%s

What it means

MinerU Cloud returned a well-formed poll response but with a non-zero business error code; fetchBatchStatus rejects it with 'poll error code=%d msg=%s' (mineru_cloud_converter.go:291). This is the API's application-level error signaling (in pollResp.Code / pollResp.Msg), e.g. the batch task ID is unknown or the task failed server-side. It is not a transport or JSON problem — the HTTP call and decode succeeded.

Source

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

	client := utils.NewSSRFSafeHTTPClient(utils.SSRFSafeHTTPClientConfig{Timeout: 30 * time.Second, MaxRedirects: 5})
	resp, err := client.Do(httpReq)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("read poll response body: %w", err)
	}

	var pollResp batchPollResponse
	if err := json.Unmarshal(respBody, &pollResp); err != nil {
		return nil, fmt.Errorf("decode poll response: %w", err)
	}
	if pollResp.Code != 0 {
		return nil, fmt.Errorf("poll error code=%d msg=%s", pollResp.Code, pollResp.Msg)
	}

	if len(pollResp.Data.ExtractResult) == 0 {
		return nil, nil
	}

	// 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")

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Read the msg value in the error — it names the server-side cause (e.g. task not found, task failed).
  2. Verify the batch ID being polled was obtained from the successful upload/create-batch response in the same session/key.
  3. Poll promptly: results may expire; re-submit the document if the task is gone.
  4. Check MinerU Cloud status/announcements if the code indicates a service-side failure.
Defensive patterns

Strategy: try-catch

Type guard

func isPollBusinessError(err error) bool {
    return err != nil && strings.HasPrefix(err.Error(), "poll error code=")
}

Try / catch

items, err := pollBatchResult(ctx, batchID)
if err != nil {
    var apiErr *MinerUPollError
    if errors.As(err, &apiErr) && apiErr.Code == errCodeTaskNotFound {
        // batch expired/unknown: re-submit the document
        return resubmitBatch(ctx, doc)
    }
    return err
}

Prevention

When it happens

Trigger: pollBatchResult -> fetchBatchStatus polls a batch ID that the MinerU Cloud service does not recognize, that has expired (results retention window passed), or that failed server-side; the response body contains code != 0.

Common situations: Polling after the batch results were purged (task finished long ago); a typo'd or reused batch ID; submitting with one API key and polling with another tenant's; MinerU Cloud service outage reporting an internal error code.

Related errors


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