Tencent/WeKnora · error
write file content: %w
Error message
write file content: %w
What it means
Immediately after creating the 'file' part, submitJob writes the whole document bytes into it via part.Write(content). If that write fails — practically only when the underlying buffer/connection errors or memory is exhausted — the error is wrapped as 'write file content'. The multipart request could not be assembled with the document payload.
Source
Thrown at internal/infrastructure/docparser/paddleocr_vl_cloud_converter.go:134
fileName := req.FileName
if fileName == "" {
ext := strings.TrimPrefix(req.FileType, ".")
if ext == "" {
ext = "pdf"
}
fileName = "document." + ext
}
var body bytes.Buffer
writer := multipart.NewWriter(&body)
_ = writer.WriteField("model", c.model)
_ = writer.WriteField("optionalPayload", string(optional))
part, err := writer.CreateFormFile("file", filepath.Base(fileName))
if err != nil {
return "", fmt.Errorf("create form file: %w", err)
}
if _, err := part.Write(content); err != nil {
return "", fmt.Errorf("write file content: %w", err)
}
writer.Close()
httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL, &body)
if err != nil {
return "", fmt.Errorf("create request: %w", err)
}
httpReq.Header.Set("Authorization", "bearer "+c.token)
httpReq.Header.Set("Content-Type", writer.FormDataContentType())
client := utils.NewSSRFSafeHTTPClient(utils.SSRFSafeHTTPClientConfig{Timeout: 60 * time.Second, MaxRedirects: 5})
resp, err := client.Do(httpReq)
if err != nil {
return "", fmt.Errorf("HTTP request: %w", err)
}
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)View on GitHub (pinned to 988cbb0330)
Solutions
- Check the wrapped cause for the underlying io error
- For large files, stream content to a temp file and use os.Open as the request body instead of buffering fully in memory
- Ensure part.Write occurs before writer.Close()
- Retest with a smaller document to isolate size-related memory pressure
Example fix
// before
var body bytes.Buffer
writer := multipart.NewWriter(&body) // large file -> memory pressure
// after
f, _ := os.CreateTemp("", "paddleocr-*")
writer := multipart.NewWriter(f) // stream to disk-backed buffer Defensive patterns
Strategy: validation
Validate before calling
if len(content) > 100<<20 { // 100 MB
return fmt.Errorf("document too large for in-memory upload: %d bytes", len(content))
} Type guard
func isPartWriteError(err error) bool {
return err != nil && strings.Contains(err.Error(), "write file content")
} Try / catch
out, err := reader.Read(ctx, req)
if isPartWriteError(err) {
if errors.Is(err, ErrWriterClosed) { return fmt.Errorf("ordering bug: write after close") }
return fmt.Errorf("upload payload write failed (consider streaming): %w", err)
} Prevention
- Prefer disk-backed streaming for documents beyond tens of MB
- Write file parts strictly before writer.Close()
- Monitor memory headroom on hosts parsing large documents
- Cap upload size at the cloud API's documented limit before submitting
When it happens
Trigger: Read -> submitJob -> part.Write(content) returns an error on a large content payload; effectively indicates an io.Writer failure on the multipart part's underlying writer (bytes.Buffer allocation failure) or an already-closed/errored writer.
Common situations: Uploading very large documents causing the in-memory bytes.Buffer to exhaust memory; writer closed prematurely after a refactor; content slice referencing unavailable data (rare).
Related errors
- write file content: %w
- create form file: %w
- failed to open file: %w
- failed to open file: %w
- failed to upload file to OSS (multipart): %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/c7564e1d403c77cb.
Report an issue: GitHub.