{"record":{"id":"4e6bd3d960515b9a","repo":"reactiveui/refit","slug":"the-configured-content-serializer-refitsettings","errorCode":null,"errorMessage":"The configured content serializer '{RefitSettings.ContentSerializer.GetType()}' does not implement ISynchronousContentDeserializer; use GetContentAsAsync instead.","messagePattern":"The configured content serializer '(.+?)' does not implement ISynchronousContentDeserializer; use GetContentAsAsync instead\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/Refit/ApiException.cs","lineNumber":343,"sourceCode":"    /// <returns>The deserialized content, or <see langword=\"default\"/> when there is no content.</returns>\n    /// <exception cref=\"NotSupportedException\">\n    /// Thrown when the configured <see cref=\"IHttpContentSerializer\"/> does not implement\n    /// <see cref=\"ISynchronousContentDeserializer\"/>.\n    /// </exception>\n    [SuppressMessage(\n        \"Design\",\n        \"SST2307:Generic method type parameters should be inferable from the parameters\",\n        Justification = \"Type parameter intentionally specified explicitly by callers.\")]\n    public T? GetContentAs<T>()\n    {\n        if (!HasContent)\n        {\n            return default;\n        }\n\n        if (RefitSettings.ContentSerializer is not ISynchronousContentDeserializer synchronousDeserializer)\n        {\n            throw new NotSupportedException(\n                $\"The configured content serializer '{RefitSettings.ContentSerializer.GetType()}' does not \"\n                + $\"implement {nameof(ISynchronousContentDeserializer)}; use {nameof(GetContentAsAsync)} instead.\");\n        }\n\n        return synchronousDeserializer.DeserializeFromString<T>(Content!);\n    }\n\n    /// <summary>\n    /// Attempts to synchronously deserialize the buffered response content as <typeparamref name=\"T\"/> without\n    /// throwing, making it usable from an exception filter:\n    /// <c>catch (ApiException ex) when (ex.TryGetContentAs&lt;Error&gt;(out var error))</c> (#1591).\n    /// </summary>\n    /// <typeparam name=\"T\">Type to deserialize the content to.</typeparam>\n    /// <param name=\"content\">The deserialized content when this returns <see langword=\"true\"/>; otherwise <see langword=\"default\"/>.</param>\n    /// <returns>\n    /// <see langword=\"true\"/> when the content was present and deserialized to a non-null value; otherwise <see langword=\"false\"/>.\n    /// </returns>\n    [SuppressMessage(","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/reactiveui/refit/blob/b455f65ecc4c97d092317e349cb775f9cfc6bcdf/src/Refit/ApiException.cs#L325-L361","documentation":"Thrown by ApiException.GetContentAs<T>() when the configured IHttpContentSerializer does not implement ISynchronousContentDeserializer. GetContentAs is a synchronous API (usable in exception filters where await is illegal); only serializers that can deserialize a string synchronously can serve it. The default SystemTextJsonContentSerializer does implement it; a custom serializer may not.","triggerScenarios":"Calling ex.GetContentAs<T>() while RefitSettings.ContentSerializer is a custom serializer lacking ISynchronousContentDeserializer. The is-pattern check fails and the NotSupportedException names the offending serializer type and points to GetContentAsAsync.","commonSituations":"Using a third-party or hand-rolled content serializer that only implements async deserialization; calling GetContentAs in a catch filter with a non-default serializer; upgrading Refit and an old custom serializer no longer satisfies the interface.","solutions":["Use the async equivalent: `await ex.GetContentAsAsync<T>()` instead of the synchronous method.","Make your custom serializer implement ISynchronousContentDeserializer (add DeserializeFromString<T>(string)).","If you only need the raw string, read ex.Content (the buffered string) directly without deserialization."],"exampleFix":"// before — custom serializer without sync deserialization\nvar err = ex.GetContentAs<Error>(); // throws NotSupportedException\n\n// after — use the async overload\nvar err = await ex.GetContentAsAsync<Error>();\n// or implement ISynchronousContentDeserializer on your serializer to keep GetContentAs","handlingStrategy":"try-catch","validationCode":"// Prefer the async API to avoid the capability check entirely.\nvar err = await ex.GetContentAsAsync<T>();","typeGuard":"// Check the serializer capability before calling the sync overload.\nstatic bool CanSyncDeserialize(RefitSettings s) =>\n    s.ContentSerializer is ISynchronousContentDeserializer;","tryCatchPattern":"T? content;\nif (ex.RefitSettings.ContentSerializer is ISynchronousContentDeserializer)\n    content = ex.GetContentAs<T>();\nelse\n    content = await ex.GetContentAsAsync<T>();","preventionTips":["Default to GetContentAsAsync; reserve GetContentAs for exception filters where await is illegal.","If you ship a custom serializer, implement ISynchronousContentDeserializer so both APIs work.","Document in your team which serializers support synchronous deserialization."],"tags":["serialization","api-exception","sync-vs-async","content-serializer"],"backgroundTag":null,"analyzedSha":"b455f65ecc4c97d092317e349cb775f9cfc6bcdf","analyzedAt":"2026-08-13T21:20:57.878Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}