{"record":{"id":"73f4cf0336a95897","repo":"Tencent/WeKnora","slug":"paddleocr-vl-cloud-submit-w","errorCode":null,"errorMessage":"PaddleOCR-VL Cloud submit: %w","messagePattern":"PaddleOCR-VL Cloud submit: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/infrastructure/docparser/paddleocr_vl_cloud_converter.go","lineNumber":68,"sourceCode":"func (c *PaddleOCRVLCloudReader) Read(ctx context.Context, req *types.ReadRequest) (*types.ReadResult, error) {\n\tif c.token == \"\" {\n\t\treturn &types.ReadResult{Error: \"PaddleOCR-VL Cloud token is not configured\"}, nil\n\t}\n\tif err := utils.ValidateURLForSSRF(c.baseURL); err != nil {\n\t\treturn &types.ReadResult{Error: fmt.Sprintf(\"PaddleOCR-VL Cloud base URL blocked by SSRF policy: %v\", err)}, nil\n\t}\n\n\tcontent := req.FileContent\n\tif len(content) == 0 {\n\t\treturn &types.ReadResult{Error: \"no file content provided\"}, nil\n\t}\n\n\tlogger.Infof(context.Background(), \"[PaddleOCR-VL Cloud] Parsing file=%s size=%d model=%s\",\n\t\treq.FileName, len(content), c.model)\n\n\tjobID, err := c.submitJob(ctx, req, content)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"PaddleOCR-VL Cloud submit: %w\", err)\n\t}\n\n\tjsonlURL, err := c.pollJob(ctx, jobID)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"PaddleOCR-VL Cloud poll: %w\", err)\n\t}\n\n\tmdContent, imagesURL, err := c.fetchResults(jsonlURL)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"PaddleOCR-VL Cloud fetch results: %w\", err)\n\t}\n\n\tmdContent = normalizeHTMLTables(mdContent)\n\n\timageRefs := c.downloadImages(mdContent, imagesURL)\n\tmdContent, imageRefs = ensureOriginalImageRef(req, mdContent, imageRefs)\n\n\tlogger.Infof(context.Background(), \"[PaddleOCR-VL Cloud] Parsed successfully, markdown=%d chars, images=%d\",","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/infrastructure/docparser/paddleocr_vl_cloud_converter.go#L50-L86","documentation":"The PaddleOCR-VL Cloud converter's Read first submits the document to the cloud API via submitJob. Any failure during that submission (marshaling, building the multipart form, creating/sending the HTTP request, or a non-success HTTP response) is wrapped as 'PaddleOCR-VL Cloud submit'. The inner error tells you which submission step failed.","triggerScenarios":"Read -> submitJob fails: optionalPayload marshal error, CreateFormFile error, write-file error, http.NewRequestWithContext error, client.Do transport error, or the cloud API returning a non-OK status for the job submission.","commonSituations":"Expired or invalid PaddleOCR-VL cloud token (401); wrong c.baseURL env config; network egress blocked; oversized upload rejected by the cloud endpoint; malformed model/optional payload rejected with 400.","solutions":["Inspect the wrapped cause (%w) — it identifies the exact failing step","Verify the PaddleOCR-VL base URL and bearer token configuration","Test cloud reachability from the deployment (egress/proxy rules)","Confirm the file is a supported type/size for the cloud API","Retry on transient 5xx/timeouts with backoff"],"exampleFix":"// before\nclient := utils.NewSSRFSafeHTTPClient(utils.SSRFSafeHTTPClientConfig{Timeout: 60 * time.Second})\n// after (bigger uploads need more time)\nclient := utils.NewSSRFSafeHTTPClient(utils.SSRFSafeHTTPClientConfig{Timeout: 300 * time.Second, MaxRedirects: 5})","handlingStrategy":"try-catch","validationCode":"if c.baseURL == \"\" || !strings.HasPrefix(c.baseURL, \"https://\") {\n    return errors.New(\"PaddleOCR-VL base URL must be set to an https endpoint\")\n}\nif c.token == \"\" {\n    return errors.New(\"PaddleOCR-VL token is required\")\n}","typeGuard":"func isSubmitFailure(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"PaddleOCR-VL Cloud submit\")\n}","tryCatchPattern":"out, err := reader.Read(ctx, req)\nif isSubmitFailure(err) {\n    if isTransient(err) { out, err = retryWithBackoff(3, reader.Read, ctx, req) }\n    if err != nil { return fmt.Errorf(\"document submit failed: %w\", err) }\n}","preventionTips":["Validate base URL and token at startup with a health check","Set timeouts proportional to expected upload size","Retry idempotent submissions on 5xx/timeouts only","Monitor cloud API quota and 401 rates"],"tags":["http","cloud-api","paddleocr","docparser"],"backgroundTag":"upstream-submit-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}