{"record":{"id":"552e5f77a0d0faa3","repo":"Tencent/WeKnora","slug":"create-form-file-w","errorCode":null,"errorMessage":"create form file: %w","messagePattern":"create form file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/infrastructure/docparser/mineru_converter.go","lineNumber":229,"sourceCode":"\t\t\"return_model_output\": \"false\",\n\t\t\"return_content_list\": \"true\",\n\t}\n\tif c.language != \"\" {\n\t\tfields[\"lang_list\"] = c.language\n\t}\n\tif c.vlmServerURL != \"\" && (strings.HasPrefix(c.backend, \"vlm-http-client\") || strings.HasPrefix(c.backend, \"hybrid-http-client\")) {\n\t\tfields[\"server_url\"] = c.vlmServerURL\n\t}\n\tfor k, v := range fields {\n\t\t_ = writer.WriteField(k, v)\n\t}\n\n\tuploadFileName := minerUUploadFileName(fileName, fileType)\n\n\t// File part\n\tpart, err := writer.CreateFormFile(\"files\", uploadFileName)\n\tif err != nil {\n\t\treturn \"\", nil, fmt.Errorf(\"create form file: %w\", err)\n\t}\n\tif _, err := part.Write(content); err != nil {\n\t\treturn \"\", nil, fmt.Errorf(\"write file content: %w\", err)\n\t}\n\twriter.Close()\n\n\thttpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, c.endpoint+\"/file_parse\", &body)\n\tif err != nil {\n\t\treturn \"\", nil, fmt.Errorf(\"create request: %w\", err)\n\t}\n\thttpReq.Header.Set(\"Content-Type\", writer.FormDataContentType())\n\n\tclient := utils.NewSSRFSafeHTTPClient(utils.SSRFSafeHTTPClientConfig{\n\t\tTimeout:      mineruTimeout,\n\t\tMaxRedirects: 5,\n\t})\n\tresp, err := client.Do(httpReq)\n\tif err != nil {","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/infrastructure/docparser/mineru_converter.go#L211-L247","documentation":"callFileParse builds a multipart/form-data request and writer.CreateFormFile('files', uploadFileName) failed. This is nearly impossible in practice (CreateFormFile only errors if the form was already closed or the field name/filename contain invalid characters), but it indicates the multipart writer is in a bad state.","triggerScenarios":"writer.CreateFormFile returns an error after writer.Close() was already called, or if uploadFileName contains invalid header characters (newlines, quotes breaking the Content-Disposition header).","commonSituations":"uploadFileName derived from req.FileName carries control characters, CR/LF injection, or pathological quotes; a refactor closed the writer before creating all parts.","solutions":["Sanitize minerUUploadFileName output: strip CR/LF, control chars, and quotes from the filename derived from req.FileName.","Verify CreateFormFile is called before writer.Close() and exactly once.","Log the computed uploadFileName to spot malformed input filenames.","This is effectively a programming/invariant bug — if it reproduces, add a unit test with hostile filenames."],"exampleFix":"// before\nuploadFileName := minerUUploadFileName(fileName, fileType)\n// after\nuploadFileName = strings.Map(func(r rune) rune {\n    if r == '\\r' || r == '\\n' || r == '\"' || unicode.IsControl(r) {\n        return '_'\n    }\n    return r\n}, minerUUploadFileName(fileName, fileType))","handlingStrategy":"validation","validationCode":"func safeUploadName(name string) string {\n    return strings.Map(func(r rune) rune {\n        if r == '\\r' || r == '\\n' || r == '\"' || unicode.IsControl(r) {\n            return '_'\n        }\n        return r\n    }, name)\n}","typeGuard":"func isHeaderSafeName(name string) bool {\n    return name != \"\" && !strings.ContainsAny(name, \"\\r\\n\\\"\\x00\")\n}","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"create form file\") {\n    // invariant violation: sanitize filename and retry once\n    return sanitizeAndRetry(req)\n}","preventionTips":["Sanitize user-supplied filenames before building multipart forms","Unit-test request building with hostile filenames (CR/LF, quotes, unicode)","Never call writer.Close() before all parts are created","Fuzz the filename-derivation function"],"tags":["multipart","request-building","mineru","input-validation"],"backgroundTag":"multipart-form-error","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}