Sending command return error 500 when returning a command response message

My command handler is correctly registered on Synapse and my app is called with a Command Message. If I return nothing in the response, then everything fine but if I return something, i.e a message like this:
{
payload : “adfadfadf”
}
Then I got an error in Synapse log:

2023-11-10 13:32:04.994 ERROR 4275 --- [ult-executor-21] a.w.r.e.AbstractErrorWebExceptionHandler : [c83d0672-63]  500 Server Error for HTTP POST "/v1/contexts/default/commands"

io.axoniq.synapse.exception.MessagingException: java.lang.NullPointerException
	at io.axoniq.synapse.command.dispatcher.impl.DefaultCommandDispatcher$request$2.invoke(DefaultCommandDispatcher.kt:43) ~[classes!/:na]
	Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
	*__checkpoint ⇢ Handler io.axoniq.synapse.transport.rest.CommandsController#sendCommandMessage(String, Mono, ServerWebExchange) [DispatcherHandler]
	*__checkpoint ⇢ org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ org.springframework.security.web.server.authorization.AuthorizationWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ org.springframework.security.web.server.authentication.logout.LogoutWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ org.springframework.security.web.server.savedrequest.ServerRequestCacheWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ org.springframework.security.web.server.context.ReactorContextWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ org.springframework.security.web.server.header.HttpHeaderWriterWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ org.springframework.security.config.web.server.ServerHttpSecurity$ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]
	*__checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
	*__checkpoint ⇢ HTTP POST "/v1/contexts/default/commands" [ExceptionHandlingWebHandler]
Original Stack Trace:
		at io.axoniq.synapse.command.dispatcher.impl.DefaultCommandDispatcher$request$2.invoke(DefaultCommandDispatcher.kt:43) ~[classes!/:na]
		at io.axoniq.synapse.command.dispatcher.impl.DefaultCommandDispatcher$request$2.invoke(DefaultCommandDispatcher.kt:40) ~[classes!/:na]
		at io.axoniq.synapse.command.dispatcher.impl.DefaultCommandDispatcher.request$lambda$1(DefaultCommandDispatcher.kt:40) ~[classes!/:na]
		at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:106) ~[reactor-core-3.4.32.jar!/:3.4.32]
		at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1839) ~[reactor-core-3.4.32.jar!/:3.4.32]
		at reactor.core.publisher.MonoCompletionStage.lambda$subscribe$0(MonoCompletionStage.java:100) ~[reactor-core-3.4.32.jar!/:3.4.32]
		at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:930) ~[na:na]
		at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:907) ~[na:na]
		at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506) ~[na:na]
		at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2073) ~[na:na]
		at io.axoniq.axonserver.connector.command.impl.CommandChannelImpl$CommandResponseHandler.onNext(CommandChannelImpl.java:386) ~[axonserver-connector-java-2023.1.0.jar!/:2023.1.0]
		at io.axoniq.axonserver.connector.command.impl.CommandChannelImpl$CommandResponseHandler.onNext(CommandChannelImpl.java:373) ~[axonserver-connector-java-2023.1.0.jar!/:2023.1.0]
		at io.grpc.stub.ClientCalls$StreamObserverToCallListenerAdapter.onMessage(ClientCalls.java:474) ~[grpc-stub-1.50.2.jar!/:1.50.2]
		at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInternal(ClientCallImpl.java:662) ~[grpc-core-1.50.2.jar!/:1.50.2]
		at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInContext(ClientCallImpl.java:647) ~[grpc-core-1.50.2.jar!/:1.50.2]
		at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37) ~[grpc-core-1.50.2.jar!/:1.50.2]
		at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:133) ~[grpc-core-1.50.2.jar!/:1.50.2]
		at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
		at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
		at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]

If you want to return something from a command handler, you should wrap it in a command handler response message. For example like this.

Thanks. In your example you have a field called “payload_type” but it seems that it is “payloadType” now

I got it, I missed the “payloadRevision” in the response. Without it, I have the NPE above.

It likely wasn’t the best example, the payload_type is a trick form the open API generator to transform the keys into idiomatic rust keys. So it’s actually transformed to payloadType in the generated client, when the rust code is transformed to a HTTP call.