Problem/Motivation
LocalOrchestraClient::validateVariable() caps the size of a variable the API is about to write, and measures it with a bare json_encode($value):
$encoded = json_encode($value); if (is_string($encoded) && strlen($encoded) > self::MAX_VARIABLE_BYTES) {
For a value JSON cannot represent (NAN, INF, a resource, a non-UTF-8 binary string) that call returns FALSE rather than a string, is_string(FALSE) is FALSE, the check is skipped, and validation passes.
The engine then encodes the same value itself, and it does not skip: Variable::setValue() uses JSON_THROW_ON_ERROR, precisely so an un-encodable value raises instead of storing the FALSE that would read back as NULL. So it throws a \JsonException.
That escapes startProcess() and setVariable(), whose documented contract on OrchestraClientInterface is to throw OrchestraClientException. A caller written against the documented contract does not catch it.
The comment that stands over the check says the opposite of what happens: "An un-encodable value (mapped to NULL by the engine) encodes tiny, so it never trips this bound." The engine has not mapped such a value to NULL since setValue() started throwing, and the reason the bound is never tripped is that the check is skipped, not that the value is small.
It is reachable from any in-process consumer of the client contract, which is public API: binary file contents passed as a variable, or a NAN out of a computation. It is not reachable over the HTTP API, since a JSON request body can carry neither.
Proposed resolution
Encode once, with JSON_THROW_ON_ERROR, and turn the failure into the exception the contract names, saying which variable it was. The size check then runs on a value that really is a string, and the comment describes what the code does.
Remaining tasks
Review the merge request.
Release notes snippet
Setting a process variable through the Orchestra client to a value JSON cannot represent now raises OrchestraClientException, the exception the client contract documents. It previously passed validation and surfaced later as an unhandled \JsonException from the engine.
AI-Generated: Yes (Claude Code was used to help draft this issue summary and to write the fix and its test on the merge request. I reviewed the work, and the new test was confirmed to fail against unpatched 1.x and to pass with the change.)
Issue fork orchestra-3622716
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
mably commentedComment #5
mably commented