You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "shashank (Jira)" <ji...@apache.org> on 2026/10/11 04:57:00 UTC

[jira] [Created] (CAMEL-25543) camel-dapr - the saveBulk and executeTransaction state operations never send their request to Dapr, so nothing is stored and the exchange completes without an error

shashank created CAMEL-25543:
--------------------------------

             Summary: camel-dapr - the saveBulk and executeTransaction state operations never send their request to Dapr, so nothing is stored and the exchange completes without an error
                 Key: CAMEL-25543
                 URL: https://issues.apache.org/jira/browse/CAMEL-25543
             Project: Camel
          Issue Type: Bug
          Components: camel-dapr
            Reporter: shashank
            Assignee: shashank


{{DaprClient}} returns a Reactor {{Mono}} for every request, and the request is sent when the {{Mono}} is subscribed to. {{DaprStateHandler}} (at main 9432ba16d026) blocks on it for {{save}} (line 78), {{get}}, {{getBulk}} and {{delete}} (line 135), but drops it for the two other operations:

{code:java}
private DaprOperationResponse saveBulkState(Exchange exchange, DaprClient client) {
    ...
    client.saveBulkState(stateRequest);              // line 90: the Mono is never subscribed to
    return DaprOperationResponse.create(stateRequest);
}

private DaprOperationResponse executeStateTransaction(Exchange exchange, DaprClient client) {
    ...
    client.executeStateTransaction(stateRequest);    // line 149: the same
    return DaprOperationResponse.create(stateRequest);
}
{code}

So {{dapr:state?stateOperation=saveBulk}} and {{dapr:state?stateOperation=executeTransaction}} do nothing: no request reaches the sidecar, no state is stored, updated or deleted, and the exchange completes successfully with the request object as the body. Nothing is logged. The component documentation describes both operations ("Store or update multiple key-value pairs in the state store in a single operation", "Execute a batch of operations (save or delete) atomically within a transaction").

A probe with the real Dapr client and no sidecar shows the behaviour of the {{Mono}}: {{client.saveBulkState(request)}} returns without an error, and {{block()}} on the same {{Mono}} fails with {{DaprException: UNAVAILABLE: io exception}}.

h3. Reproduction

Four new tests in {{DaprStateTest}} (mocked {{DaprClient}} as in the existing tests; the mocked {{Mono}} stores the states or operations of the request when it is subscribed to, or fails). On main, twice:
{noformat}
testSaveBulkSendsTheStates:               expected: <[StateKeyValue{key='k1', ...}, StateKeyValue{key='k2', ...}]> but was: <[]>
testSaveBulkFailure:                      Expected java.lang.IllegalStateException to be thrown, but nothing was thrown.
testExecuteTransactionSendsTheOperations: expected: <[TransactionalStateOperation{operationType='UPSERT', ...}]> but was: <[]>
testExecuteTransactionFailure:            Expected java.lang.IllegalStateException to be thrown, but nothing was thrown.
{noformat}
The existing {{testSaveBulk}} and {{testExecuteTransaction}} return {{Mono.empty()}} and only check the response object, so they do not notice it.

h3. Proposed fix

{{saveBulkState}} and {{executeStateTransaction}} block on the {{Mono}}, as the other four state operations do. The request is sent, and a request that Dapr rejects (or a sidecar that cannot be reached) fails the exchange. 4.23 upgrade guide note added next to the existing camel-dapr note. camel-dapr with the fix: 64 tests, 0 failures.

Found with a search for calls on asynchronous clients whose result is dropped, and a small Lean 4 model of the handler (the store as key/value pairs, a Mono as a deferred function that may fail): main is proved to leave the store unchanged and to report success for every request, so it is wrong whenever the request would change the store or would be rejected; the fix is proved equal to "apply the operations or fail the exchange". Confirmed with the real handler, and the laziness of the Mono with the real client.

Affected: main, camel-4.22.x, camel-4.18.x, camel-4.14.x (same two lines, GitHub contents API); the component was added in 4.12.

Duplicate check (2026-10-11): JIRA text "dapr" with "saveBulk", "executeTransaction" or "state" (1: CAMEL-23630, header filter); GitHub open pull requests for camel-dapr: none. No open pull request changes {{DaprStateHandler}}.

_Filed with Claude Code on behalf of allthingssecurity._




--
This message was sent by Atlassian Jira
(v8.20.10#820010)