Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] ServiceBusReceivedMessage.Body.ToString() throws System.ArgumentNullException: Value cannot be null. (Parameter 'bytes') #48178

Open
rglos opened this issue Feb 7, 2025 · 6 comments
Assignees
Labels
Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. issue-addressed Workflow: The Azure SDK team believes it to be addressed and ready to close. question The issue doesn't require a change to the product in order to be resolved. Most issues start as that Service Bus

Comments

@rglos
Copy link

rglos commented Feb 7, 2025

Library name and version

Azure.Messaging.ServiceBus 7.18.3

Describe the bug

Using Azure.Messaging.ServiceBus version 7.18.3, a System.ArgumentNullException: Value cannot be null. (Parameter 'bytes')exception is thrown when calling .Body.ToString();

This however works fine if using Azure.Messaging.ServiceBus version 7.18.1.

Expected behavior

I would expect that even if the message body is null on a ServiceBusReceivedMessage, it would not throw when attempting to get the message body using Body.ToString().

Actual behavior

It throws an exception which means we will have to write a method to handle and catch the exception to update our code.

Reproduction Steps

To duplicate this, create a new MSTest project and add a reference to Azure.Messaging.ServiceBus version 7.18.1.

Paste in the following test and run it to confirm it works fine:

using Azure.Messaging.ServiceBus;

namespace ServiceBusMessageBodyTestNew
{
    [TestClass]
    public sealed class Test1
    {
        [TestMethod]
        public void Body_ToString_ShouldNotThrow()
        {
            // Arrange
            var message = ServiceBusModelFactory.ServiceBusReceivedMessage(body: null);
            var expected = string.Empty;

            // Act
            var actual = message.Body.ToString();

            // Assert
            Assert.AreEqual(expected, actual);
        }
    }
}

Create a second MSTest project and add a reference to Azure.Messaging.ServiceBus version 7.18.3.

Paste the same code into a new test and you will receive the following error:

 Body_ToString_ShouldNotThrow
   Source: Test1.cs line 9
   Duration: 68 ms

  Message: 
Test method ServiceBusMessageBodyTestNew.Test1.Body_ToString_ShouldNotThrow threw exception: 
System.ArgumentNullException: Value cannot be null. (Parameter 'bytes')

  Stack Trace: 
ArgumentNullException.Throw(String paramName)
Encoding.GetString(Byte* bytes, Int32 byteCount)
BinaryData.ToString()
Test1.Body_ToString_ShouldNotThrow() line 16
RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

Environment

Using Visual Studio 2022 and OS is Windows 11.

@github-actions github-actions bot added Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team question The issue doesn't require a change to the product in order to be resolved. Most issues start as that Service Bus labels Feb 7, 2025
Copy link

github-actions bot commented Feb 7, 2025

Thank you for your feedback. Tagging and routing to the team member best able to assist.

@jsquire jsquire assigned jsquire and unassigned JoshLove-msft Feb 7, 2025
@jsquire
Copy link
Member

jsquire commented Feb 7, 2025

Hi @rglos. This is by design. The model factory intentionally accepts parameters as-is and does not attempt to transform them, allowing tests flexibility and full control over scenarios. In this case, you are calling ToString on a null reference, which you explicitly passed. Passing BinaryData.Empty from the latest System.Memory.Data package or new BinaryData(Array.Empty<byte>()) would set an empty body rather than a null.

@jsquire jsquire added the issue-addressed Workflow: The Azure SDK team believes it to be addressed and ready to close. label Feb 7, 2025
Copy link

github-actions bot commented Feb 7, 2025

Hi @rglos. Thank you for opening this issue and giving us the opportunity to assist. We believe that this has been addressed. If you feel that further discussion is needed, please add a comment with the text "/unresolve" to remove the "issue-addressed" label and continue the conversation.

@github-actions github-actions bot removed the needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team label Feb 7, 2025
@rglos
Copy link
Author

rglos commented Feb 10, 2025

Hi @rglos. This is by design. The model factory intentionally accepts parameters as-is and does not attempt to transform them, allowing tests flexibility and full control over scenarios. In this case, you are calling ToString on a null reference, which you explicitly passed. Passing BinaryData.Empty from the latest System.Memory.Data package or new BinaryData(Array.Empty<byte>()) would set an empty body rather than a null.

I understand your perspective, however due note that it behaves differently using the old version and breaks with only a minor version updated (7.18.1 to 7.18.3).

Also, I could simply be oblivious, and as a user of the API not explicitly set the body via something like var message = ServiceBusModelFactory.ServiceBusReceivedMessage(); and be left scratching my head as to why it's suddenly throwing.

For now, we have handled this case by adding an extension method which may be useful for the next person/team to come along and find this:

    /// <summary>
    /// Extensions to the <see cref="ServiceBusReceivedMessage"/> class.
    /// </summary>
    public static class ServiceBusReceivedMessageExtensions
    {
        /// <summary>
        /// Get the <see cref="ServiceBusReceivedMessage.Body"/> value as a string without throwing an exception if the value is null.
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        /// <remarks>
        /// We discovered this issue when updating the our --redacted Azure Function-- to use the non-beta NuGet package for Azure.AI.OpenAPI.  See --Jira ticket redacted--.
        /// 
        /// Calling Body.ToString() on a ServiceBusReceivedMessage with a null Body value will throw a NullReferenceException.  We need to handle this 
        /// case without throwing an exception. We reached to Microsoft - see https://github.com/Azure/azure-sdk-for-net/issues/48178.
        /// 
        /// So for now this is our fix.  If Microsoft fixes it, we won't need this.
        /// </remarks>
        public static string GetBodyAsStringWithoutThrowingWhenNull(this ServiceBusReceivedMessage message)
        {
            var bodyHasValue = message.Body.ToArray().Length > 0;
            if (!bodyHasValue)
            {
                return string.Empty;
            }

            var bodyValue = message.Body.ToString();

            return bodyValue;
        }
    }

@jsquire
Copy link
Member

jsquire commented Feb 10, 2025

@rglos: Thank you for the additional context, and apologies - I was not connecting the dots for the end-to-end scenario. There was no change to Service Bus between versions for how we treat null bodies - we always use it as-is. It looks like what you're seeing is a known bug in System.Memory.Data v6.x which impacts how an empty BinaryData reacts to ToString calls. The version used by Service Bus moved to the 6.x line via the version update to Azure.Core. (see: BinaryData.Empty.ToString throws ArgumentNullException)

The .NET runtime team has decided not to backport the fix in the 8.x+ versions to the 6.x line. The Azure dependencies are currently in the process of transitioning to the 8.x line, which will resolve the error that you're seeing. In the interim, you can work around this by taking a direct reference to System.Memory.Data v8.0.0 or above in your application, which will hoist the version used by the Service Bus library.

@rglos
Copy link
Author

rglos commented Feb 10, 2025

Thanks for giving this a second look and the explanation @jsquire. Very helpful.

I think we'll keep our extension method for now instead of taking a direct reference and in a future NuGet upgrade months down the road when this is worked itself out, we can remove using the extension method to handle it.

Again, though, much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. issue-addressed Workflow: The Azure SDK team believes it to be addressed and ready to close. question The issue doesn't require a change to the product in order to be resolved. Most issues start as that Service Bus
Projects
None yet
Development

No branches or pull requests

3 participants