{"record":{"id":"9b12ee0f11278098","repo":"reactiveui/refit","slug":"unexpected-parameter-type-in-a-multipart-request","errorCode":null,"errorMessage":"Unexpected parameter type in a Multipart request. Parameter {fileName} 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.Reflection/RequestBuilderImplementation.Payload.cs","lineNumber":369,"sourceCode":"\n        // Fallback to serializer\n        Exception e;\n        try\n        {\n            multiPartContent.Add(\n                _settings.ContentSerializer.ToHttpContent(itemValue),\n                parameterName);\n            return;\n        }\n        catch (Exception ex)\n        {\n            // Eat this since we're about to throw as a fallback anyway\n            e = ex;\n        }\n\n        const string allowedTypes = \"String, Stream, FileInfo, Byte array and anything that's JSON serializable\";\n        var parameterType = itemValue.GetType().Name;\n        throw new ArgumentException(\n            $\"Unexpected parameter type in a Multipart request. Parameter {fileName} is of type {parameterType}, whereas allowed types are {allowedTypes}\",\n            nameof(itemValue),\n            e);\n    }\n\n    /// <summary>Appends query key/value pairs for a single parameter value.</summary>\n    /// <param name=\"queryParamsToAdd\">The list receiving query parameters.</param>\n    /// <param name=\"param\">The parameter value.</param>\n    /// <param name=\"parameterInfo\">Reflection info for the parameter.</param>\n    /// <param name=\"queryPath\">The query key path for the parameter.</param>\n    /// <param name=\"queryAttribute\">The query attribute governing formatting.</param>\n    internal void AppendQueryParameter(\n        List<QueryParameterEntry> queryParamsToAdd,\n        object? param,\n        ParameterInfo parameterInfo,\n        string queryPath,\n        QueryAttribute queryAttribute)\n    {","sourceCodeStart":351,"sourceCodeEnd":387,"githubUrl":"https://github.com/reactiveui/refit/blob/b455f65ecc4c97d092317e349cb775f9cfc6bcdf/src/Refit.Reflection/RequestBuilderImplementation.Payload.cs#L351-L387","documentation":"While building a multipart/form-data request body, Refit attempts to serialize each part with the configured content serializer and, on failure, falls back to an allowlist of multipart-native types (String, Stream, FileInfo, byte[], or anything JSON-serializable). This throw is the fallback: the part value is none of those and serialization also failed, with the original exception attached as inner.","triggerScenarios":"A [Multipart] method parameter value is a type that is neither a multipart-native type nor serializable by the content serializer, e.g. an anonymous object, a Type instance, a delegate, or a POCO whose serializer threw (missing parameterless constructor, circular reference).","commonSituations":"Passing a complex DTO the serializer cannot handle; a property whose JSON serialization fails (circular refs, missing ctor); passing an unsupported collection as a part; serializer misconfigured for the payload.","solutions":["Inspect the inner exception 'e' to see the exact serialization failure and fix that (add a parameterless constructor, resolve circular references, etc.).","Convert the part to a supported multipart type: serialize to a string/byte[] yourself, or pass a Stream/FileInfo for file parts.","Ensure the content serializer configured in RefitSettings can handle the part's type.","For complex objects meant as JSON parts, confirm they are plain serializable POCOs."],"exampleFix":"// before\n[Multipart]\n[Post(\"/upload\")]\nTask UploadAsync([AliasAs(\"meta\")] SomeUnserializableType meta);\n\n// after (serialize to a string part you control)\n[Multipart]\n[Post(\"/upload\")]\nTask UploadAsync([AliasAs(\"meta\")] string metaJson);\n// caller: await api.UploadAsync(JsonConvert.SerializeObject(meta));","handlingStrategy":"type-guard","validationCode":"static bool IsMultipartAllowed(object? value) {\n    if (value is null) return true;\n    var t = value.GetType();\n    return value is string or Stream or System.IO.FileInfo\n        || t == typeof(byte[])\n        || (t.IsClass && t.GetConstructor(Type.EmptyTypes) is not null); // crude JSON-serializable check\n}","typeGuard":"static bool IsMultipartPart(object value) =>\n    value is string or Stream or System.IO.FileInfo or byte[];","tryCatchPattern":null,"preventionTips":["Pre-serialize complex parts to string/byte[] before passing to a [Multipart] method.","Keep multipart parts to String, Stream, FileInfo, byte[], or simple serializable POCOs.","Unit-test each part type against the configured content serializer."],"tags":["refit","multipart","serialization","attributes","runtime"],"backgroundTag":null,"analyzedSha":"b455f65ecc4c97d092317e349cb775f9cfc6bcdf","analyzedAt":"2026-08-13T21:20:57.878Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}