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
- Read the msg value in the error — it names the server-side cause (e.g. task not found, task failed).
- Verify the batch ID being polled was obtained from the successful upload/create-batch response in the same session/key.
- Poll promptly: results may expire; re-submit the document if the task is gone.
- 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
- Parse the code/msg out of the error message to branch on task-not-found vs task-failed.
- Poll promptly after submission; results can expire server-side.
- Use the same API key/tenant for create-batch and poll calls.
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.