{"record":{"id":"e236bda2a5fefd12","repo":"Tencent/WeKnora","slug":"mineru-cloud-file-upload-w","errorCode":null,"errorMessage":"MinerU Cloud file upload: %w","messagePattern":"MinerU Cloud file upload: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/infrastructure/docparser/mineru_cloud_converter.go","lineNumber":85,"sourceCode":"\text := filepath.Ext(req.FileName)\n\tif ext == \"\" && req.FileType != \"\" {\n\t\text = \".\" + req.FileType\n\t}\n\tif ext == \"\" {\n\t\text = \".pdf\"\n\t}\n\tfileName := strings.TrimSuffix(req.FileName, ext) + ext\n\tif fileName == ext {\n\t\tfileName = \"document\" + ext\n\t}\n\n\tbatchID, uploadURL, err := c.applyUploadURLs(ctx, fileName, ext)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"MinerU Cloud apply upload URLs: %w\", err)\n\t}\n\n\tif err := c.uploadFile(ctx, uploadURL, content); err != nil {\n\t\treturn nil, fmt.Errorf(\"MinerU Cloud file upload: %w\", err)\n\t}\n\n\tmdContent, imageRefs, err := c.pollBatchResult(ctx, batchID)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"MinerU Cloud poll: %w\", err)\n\t}\n\n\tmdContent, imageRefs = ensureOriginalImageRef(req, mdContent, imageRefs)\n\n\treturn &types.ReadResult{\n\t\tMarkdownContent: mdContent,\n\t\tImageRefs:       imageRefs,\n\t}, nil\n}\n\n// --- batch upload API ---\n\ntype batchApplyResponse struct {","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/infrastructure/docparser/mineru_cloud_converter.go#L67-L103","documentation":"After obtaining an upload URL, Read uploads the raw document bytes with uploadFile; any failure is wrapped as \"MinerU Cloud file upload: %w\". The presigned-URL PUT/POST to the storage backend failed, so the batch never gets processable content.","triggerScenarios":"Read -> uploadFile returned an error when PUT-ing the document bytes to the presigned uploadURL: network failure, non-2xx storage response, timeout, or body mismatch with the signed request.","commonSituations":"Uploading files larger than the storage limit; presigned URL expired between applyUploadURLs and upload (slow local processing); wrong Content-Type/header not matching signature; TLS-intercepting proxy breaking the upload; network interruption mid-upload.","solutions":["Check the wrapped cause for HTTP status; a 403 on a presigned URL usually means expired signature or header mismatch — retry the whole Read (fresh URLs are issued per call).","Verify the file size is within the MinerU/storage upload limit; compress or split large documents.","Ensure stable network connectivity to the storage host; retry after transient failures.","Do not modify the request headers/body relative to what the signature expects."],"exampleFix":"// before: reusing an old presigned URL after a long delay\nuploadURL := cachedUploadURLFromYesterday\nclient.uploadFile(ctx, uploadURL, content) // 403 expired\n// after: always fetch fresh URLs immediately before upload\nbatchID, uploadURL, err := client.applyUploadURLs(ctx, fileName, ext)\nif err != nil { return nil, err }\nif err := client.uploadFile(ctx, uploadURL, content); err != nil { return nil, err }","handlingStrategy":"retry","validationCode":"const maxUploadBytes = 200 << 20 // confirm against MinerU/storage limits\nif int64(len(content)) > maxUploadBytes {\n    return fmt.Errorf(\"document too large to upload: %d bytes\", len(content))\n}","typeGuard":null,"tryCatchPattern":"res, err := converter.Read(ctx, req)\nif err != nil {\n    if strings.Contains(err.Error(), \"file upload\") {\n        log.Warnf(\"upload to presigned URL failed: %v — retrying Read (fresh presigned URLs)\", err)\n        return retryWithBackoff(ctx, 3, func() error { return readAgain(ctx, req) })\n    }\n    return err\n}","preventionTips":["Upload immediately after obtaining presigned URLs; never cache them across requests (they expire).","Check document size limits before calling Read; split or compress oversized documents.","Ensure the upload path has stable network access and no TLS-intercepting proxy altering requests.","Retry idempotently: each Read call issues a fresh batch, so a failed upload can simply be retried."],"tags":["http","upload","cloud-storage","network"],"backgroundTag":"file-upload-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}