backblaze icon indicating copy to clipboard operation
backblaze copied to clipboard

Missing `readBucketLogging` Capability Causes JSON Serialization Error

Open tcortega opened this issue 11 months ago • 2 comments

When calling ConnectAsync to start the StorageClient against Backblaze’s API, the following error occurs:

[23:10:28 ERR] Async initialization for Api.Infrastructure.Storage.StorageInitializer failed
Newtonsoft.Json.JsonSerializationException: Error converting value "readBucketLogging" to type 'Bytewizer.Backblaze.Models.Capability'. Path 'allowed.capabilities[15]', line 23, position 25.
 ---> System.ArgumentException: Requested value 'readBucketLogging' was not found.

It appears that the readBucketLogging capability is missing in the library's enum definition. Consequently, the JSON deserialization fails.

Simple Workaround

Below is a quick workaround to help others who may be encountering the same issue. Please note that this is not the ideal solution, the preferred fix is for the library to add the missing readBucketLogging value.

Step 1: Create a Custom Fallback Converter

public sealed class FallbackEnumConverter : StringEnumConverter
{
    public FallbackEnumConverter(NamingStrategy namingStrategy) : base(namingStrategy) { }

    public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
    {
        try
        {
            return base.ReadJson(reader, objectType, existingValue, serializer);
        }
        catch (JsonSerializationException)
        {
            // Returns a default instance if we can’t find a matching enum value
            return Activator.CreateInstance(objectType);
        }
    }
}

Step 2: Replace the Default Converter (Example with Unsafe Accessors)

If you’re using .NET 8+, you can leverage UnsafeAccessor to get at the library’s internal fields and properties. Here’s a stripped-down example of how you might do so:

public static class BackblazeWorkaround
{
    [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_client")]
    private static extern ref IApiClient GetClient(Storage storage);

    [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "get_JsonSerializer")]
    private static extern JsonSerializer GetJsonSerializer(ApiRest apiRest);

    public static void ApplyFallbackEnumConverter(Storage storage)
    {
        var apiClient = GetClient(storage);
        var jsonSerializer = GetJsonSerializer((ApiRest)apiClient);
        jsonSerializer.JsonSettings.Converters.RemoveAt(0);
        jsonSerializer.JsonSettings.Converters.Add(
            new FallbackEnumConverter(new CamelCaseNamingStrategy())
        );
    }
}

tcortega avatar Feb 28 '25 02:02 tcortega

It's been 2 1/2 months since this issue was created with no action taken by the repo owner. No disrespect intended, but the software is currently broken and for those of us who'd like to use it, we should discuss a path forward.

AZDeveloper777 avatar May 20 '25 05:05 AZDeveloper777

Merged ReadBucketLogging and WriteBucketLogging to represent permissions for reading and writing bucket logging information, respectively in version release v1.1.1.

microcompiler avatar Jun 07 '25 23:06 microcompiler