{"record":{"id":"3c1c35df2c9fd23c","repo":"reactiveui/refit","slug":"unexpected-parameter-type-in-a-multipart-request-3c1c35","errorCode":null,"errorMessage":"Unexpected parameter type in a Multipart request. Parameter {fieldName} is of type {parameterType}, whereas allowed types are {allowedTypes}","messagePattern":"Unexpected parameter type in a Multipart request\\. Parameter (.+?) is of type (.+?), whereas allowed types are (.+?)","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Refit/GeneratedRequestRunner.cs","lineNumber":580,"sourceCode":"    /// <summary>Serializes a multipart part through the content serializer, wrapping a failure with the same descriptive\n    /// argument exception the reflection request builder raises for an unserializable part.</summary>\n    /// <typeparam name=\"T\">The declared part type.</typeparam>\n    /// <param name=\"settings\">The Refit settings to use.</param>\n    /// <param name=\"value\">The part value to serialize.</param>\n    /// <param name=\"fieldName\">The multipart field name, named in the failure message.</param>\n    /// <returns>The serialized HTTP content.</returns>\n    /// <exception cref=\"ArgumentException\">The content serializer could not serialize the value.</exception>\n    public static HttpContent SerializeMultipartPart<T>(RefitSettings settings, T value, string fieldName)\n    {\n        try\n        {\n            return settings.ContentSerializer.ToHttpContent(value);\n        }\n        catch (Exception ex)\n        {\n            var parameterType = value?.GetType().Name;\n            const string allowedTypes = \"String, Stream, FileInfo, Byte array and anything that's JSON serializable\";\n            throw new ArgumentException(\n                $\"Unexpected parameter type in a Multipart request. Parameter {fieldName} is of type {parameterType}, whereas allowed types are {allowedTypes}\",\n                nameof(value),\n                ex);\n        }\n    }\n\n    /// <summary>Determines whether the body should use the legacy JSON enum member.</summary>\n    /// <param name=\"serializationMethod\">The body serialization method.</param>\n    /// <returns><see langword=\"true\"/> for the legacy JSON value.</returns>\n    /// <remarks>Compares the underlying value so callers never name the obsolete member and raise CS0618.</remarks>\n    internal static bool IsObsoleteJsonSerializationMethod(BodySerializationMethod serializationMethod) =>\n        (int)serializationMethod == ObsoleteJsonBodySerializationMethodValue;\n\n    /// <summary>Resolves the single-character delimiter for a non-multi collection format.</summary>\n    /// <param name=\"collectionFormat\">The collection format.</param>\n    /// <returns>The delimiter character.</returns>\n    internal static char CollectionDelimiter(CollectionFormat collectionFormat) =>\n        collectionFormat switch","sourceCodeStart":562,"sourceCodeEnd":598,"githubUrl":"https://github.com/reactiveui/refit/blob/b455f65ecc4c97d092317e349cb775f9cfc6bcdf/src/Refit/GeneratedRequestRunner.cs#L562-L598","documentation":"SerializeMultipartPart catches any exception from the configured IHttpContentSerializer.ToHttpContent and rethrows it as an ArgumentException, reporting the field name, the runtime type of the value, and the allowed types. It is a wrapper that surfaces an inner serializer failure with a Refit-friendly message.","triggerScenarios":"A multipart method receives an argument whose type the content serializer cannot handle. For the default SystemTextJsonContentSerializer this means a type that fails JSON serialization; for other serializers it means whatever they reject. The exception is thrown while building the multipart body, before the request is sent.","commonSituations":"Posting a complex object with circular references or non-serializable members in a multipart part; passing a type with no public serializable members; a custom IHttpContentSerializer that throws on a given type; a value whose JSON converter throws (e.g. unsupported polymorphism).","solutions":["Pass one of the supported types: String, Stream, FileInfo, byte[], or a JSON-serializable object","If the value is a complex type, make it JSON-serializable (public settable props, no cycles, supported converters)","Inspect the inner exception (ex.InnerException) to find the real serialization error and address that","Register a custom JsonConverter for the type or use a different IHttpContentSerializer that supports it"],"exampleFix":"// before\nTask PostAsync([Body(BodySerializationMethod.UrlEncoded)] MultiPartPart part);\nmultipart.Add(new MultipartPart { File = someNonSerializableObject }); // serializer throws => wrapped\n\n// after\nmultipart.Add(Encoding.UTF8.GetBytes(jsonString), \"payload\"); // byte[] is allowed\n// or pass a JSON-serializable DTO with public properties","handlingStrategy":"try-catch","validationCode":"static bool IsMultipartSupported<T>(T value) =>\n    value is string or Stream or FileInfo or byte[];\n\nif (!IsMultipartSupported(part))\n    // ensure the DTO is JSON-serializable before adding it\n    _ = JsonSerializer.SerializeToUtf8Bytes(part); // throws early with a clearer error\nmultipart.Add(part, fieldName);","typeGuard":"static bool IsMultipartAllowedType(object? value) =>\n    value is string or Stream or FileInfo or byte[];","tryCatchPattern":"try { await api.UploadAsync(parts); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Unexpected parameter type in a Multipart request\"))\n{\n    var serializerError = ex.InnerException?.Message ?? ex.Message;\n    logger.LogError(\"Multipart serialization failed: {Error}\", serializerError);\n}","preventionTips":["Restrict multipart part values to String, Stream, FileInfo, byte[], or simple JSON DTOs","Verify complex DTOs serialize successfully before adding them as multipart parts","Inspect InnerException to find the underlying serializer error quickly","Add a serializer smoke test for each DTO type used in multipart uploads"],"tags":["serialization","multipart","content-serializer","argument","json"],"backgroundTag":null,"analyzedSha":"b455f65ecc4c97d092317e349cb775f9cfc6bcdf","analyzedAt":"2026-08-13T21:20:57.878Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}