Skip to content

The task run: script is meant to run embedded as part of the workflow definition #1180

Closed

Description

@fjtirado

I tried this:

Java SDK reference implementation was broken because of #1129

This happened:

Unfortunately this PR breaks SDK Java reference implementation for scripts.
The PR was assuming that a script implementation will consist on an external call to the os script command , which as the Java implemenation proof, is not necesarily true.
We should partially revert it.
We should remove stdin argument for script call, and revert back script arguments from list to map (since both JS and Python supports named arguments). Then we restore the deleted script example (that was a clear indication of breakign backward compatibilitty that should have prevented the merge) and remove the script example that was added.
We can keep new stdin argument for shell and container (it is optional and a nice addition).

I expected this:

No response

Is there a workaround?

No response

Anything else?

No response

Area(s)

No response

Community Notes

  • Please vote by adding a 👍 reaction to the issue to help us prioritize.
  • If you are interested to work on this issue, please leave a comment.name: Bug Report 🐞

Activity

  1. added
    change: fixSomething isn't working. Impacts in a minor version change.
    area: specChanges in the Specification
    on Aug 4, 2026
  2. self-assigned this
    on Aug 4, 2026
  3. added theissue type on Aug 4, 2026
  4. added this to the v1.1.0 milestone on Aug 4, 2026
  5. fjtirado commented on Aug 4, 2026

    @fjtirado
    CollaboratorAuthor

    For references, see how Map of arguments are handled in SDK reference implementation (and why this should have not been changed)

    For JS and Python, they are used as named arguments, as supported by the languages

    JS implementation is embedded

    https://github.com/open-workflow-specification/sdk-java/blob/main/impl/javascript/src/main/java/io/serverlessworkflow/impl/executors/script/js/JavaScriptScriptTaskRunner.java#L77

    And it can run this example

    https://github.com/open-workflow-specification/sdk-java/blob/main/impl/test/src/test/resources/workflows-samples/run-script/console-log-args.yaml

    Python one is base command line, but still it can handle named args gracefullly

    https://github.com/open-workflow-specification/sdk-java/blob/main/impl/python/src/main/java/io/serverlessworkflow/impl/executors/script/python/PythonScriptTaskRunner.java#L55-L64

    For shell, we are compounding name=value as shell argument, if value is present
    https://github.com/open-workflow-specification/sdk-java/blob/main/impl/core/src/main/java/io/serverlessworkflow/impl/executors/RunShellExecutor.java#L54-L60

    So you can have only key ones
    https://github.com/open-workflow-specification/sdk-java/blob/main/impl/test/src/test/resources/workflows-samples/run-shell/echo-with-args-only-key.yaml
    or key-value ones
    https://github.com/open-workflow-specification/sdk-java/blob/main/impl/test/src/test/resources/workflows-samples/run-shell/echo-with-args-key-value-jq.yaml (so the key part is fixed and the value result of an argument evalution, heavily improving user experience)

  6. fjtirado commented on Aug 4, 2026

    @fjtirado
    CollaboratorAuthor

    This is the proposed diff
    Note that stdin is removed for Script, because as mentioned in slack it is of dubious utility for scripts, but it can be kept.
    What needs to be restored (because it breaks current implementation) is the arguments to be a map rather than a list. Note that a map can be converted to a list so other implementations will still work with reasonable trivial changes, while the opposite is not true (converting a list to map should be based on arg position, which is really ugly),
    Besides that, having a map allows user to define narrower jq expressions, which improves user experience, as shown in previous comment.

    diff --git a/schema/workflow.yaml b/schema/workflow.yaml
    index 88c92bd..b997524 100644
    --- a/schema/workflow.yaml
    +++ b/schema/workflow.yaml
    @@ -877,16 +877,11 @@
                           type: string
                           title: ScriptLanguage
                           description: The language of the script to run.
    -                    stdin:
    -                      type: string
    -                      title: ScriptStdin
    -                      description: A runtime expression, if any, to the script as standard input (stdin).
                         arguments:
    -                      type: array
    +                      type: object
                           title: ScriptArguments
    -                      description: A list of the arguments, if any, to the script as argv
    -                      items:
    -                        type: string
    +                      description: A key/value mapping of the arguments, if any, to use when running the configured script.
    +                      additionalProperties: true
                         environment:
                           type: object
                           title: ScriptEnvironment
    @@ -929,11 +924,10 @@
                           title: ShellStdin
                           description: A runtime expression, if any, to the shell command as standard input (stdin).
                         arguments:
    -                      type: array
    +                      type: object
                           title: ShellArguments
    -                      description: A list of the arguments, if any, to the shell command as argv
    -                      items:
    -                        type: string
    +                      description: A list of the arguments of the shell command to run.
    +                      additionalProperties: true
                         environment:
                           type: object
                           title: ShellEnvironment
    
    
  7. ricardozanini commented on Aug 4, 2026

    @ricardozanini
    Collaborator

    Disclaimer: I used AI to organize my ideas before submiting a PR.


    Assessment of Issue #1180

    What PR #1129 Changed

    PR #1129 by @hirenr made three changes to run:script and run:shell:

    1. Changed arguments from object (map) to array (string list) — for script, shell, and container
    2. Added stdin — a new string property on all three (script, shell, container)
    3. Deleted the old run-script-with-arguments.yaml example — which used map-based arguments — and replaced it with a new stdin+argv example

    PR #1129 Author's Rationale

    The author's motivation was to align the spec with a CLI/OS execution model:

    • Arguments as string[] map directly to argv (positional CLI arguments)
    • stdin provides a clean separation between data input (piped via stdin) and arguments
    • Avoids "injection of code into scripts" — data goes through stdin, not embedded in script code
    • Makes scripts "portable" — they work the same way inside and outside the workflow engine

    Why This Breaks the Java SDK (and the Spec Philosophy)

    @fjtirado makes a strong case that the change was misguided for scripts specifically:

    1. Scripts are not CLIs. The PR assumed scripts are invoked as external OS commands (like node script.js arg1 arg2). But the Java SDK embeds script execution — JavaScript runs via GraalJS, Python via Jython/subprocess. Named arguments map naturally to language features:

      • JS: arguments map entries become named variables accessible in the script (e.g., console.log(greetings) — see
        console-log-args.yaml)
      • Python: map entries become named arguments
      • Shell: map entries become --key=value or positional flags (see
        echo-with-args-key-value-jq.yaml)
    2. A map is strictly more expressive than a list. You can always convert {a: 1, b: 2} to ["a", "1", "b", "2"], but you can't go the other way without convention-based parsing. The old map format let users write focused jq expressions like '--user': '${.user}' with clear semantics.

    3. The deleted example was a red flag. The old run-script-with-arguments.yaml used arguments: {message: "${ .message }"} and console.log(message) — direct named variable access. PR feat: baseline run:script, run:container and run:shell to support stdin and argv #1129 deleted it because it no longer fit the new array model, which should have signaled backward incompatibility.

    4. stdin for scripts is dubious. For embedded script engines (GraalJS, Jython), there's no real stdin pipe. It only makes sense when scripts are executed as OS subprocesses.

    Proposed Fix

    Property Script Shell Container
    arguments Revert to object (map) Revert to object (map) Keep as array (makes sense for CMD argv)
    stdin Remove (dubious for embedded engines) Keep (useful for piping data) Keep (useful for piping data)

    For container, keeping arguments as an array makes sense — containers genuinely receive argv via their entrypoint/CMD. But for scripts and shell commands, the map format is more expressive and better matches how SDK implementations actually work.

    The example run-script-with-stdin-and-arguments.yaml should be replaced with the restored original run-script-with-arguments.yaml, and run-shell-stdin-and-arguments.yaml should be updated to use the map format for arguments (while keeping stdin).

  8. changed the title [-]Partially revert https://github.com/open-workflow-specification/specification/pull/1129[/-] [+]The task `run: script` is meant to run embedded as part of the workflow definition[/+] on Aug 4, 2026
  9. added 4 commits that reference this issue on Aug 4, 2026
    68a6930
    2d9baa4
    dd01baa
    db039d0
  10. cdavernas commented on Sep 27, 2026

    @cdavernas
    Collaborator

    I think there is a major issue with the statement that a map is "strictly more expressive than a list".

    A map and an array model two different things.

    A map works well for named bindings:

    arguments:
      message: Hello
      count: 3

    But it cannot naturally represent positional / unnamed arguments:

    script.sh input.txt output.txt

    or:

    grep -r foo .

    With an object, you would have to invent semantics such as:

    arguments:
      input: input.txt
      output: output.txt

    At that point, the runtime has to decide how those keys map to argument order. That is no longer an argv model, but an implementation-specific binding convention.

    It also breaks down for cases where order matters, where the same option appears multiple times, or where arguments are unnamed:

    ["foo", "--include", "a", "--include", "b", "bar"]
    

    There is no natural, lossless object representation for that.

    So this claim:

    You can always convert {a: 1, b: 2} to ["a", "1", "b", "2"], but you can't go the other way

    is misleading. You can serialize a map into an array by defining a convention, but that does not mean the two representations have equivalent semantics. Likewise, an arbitrary argv cannot be represented as a map without inventing names, conventions, or potentially losing ordering and duplicates.

    I think the real conceptual distinction should be:

    • arguments: array → invocation arguments / argv
    • named bindings / variables → script execution context, and arguably a separate property

    For shell, I would be even more strongly against reverting arguments to an object. Shell commands are inherently ordered, and an array is the natural representation:

    arguments:
      - --user
      - ${ .user }
      - --verbose
      - input.txt

    A map would make common CLI patterns awkward or impossible.

    So I think the proposed fix should be reconsidered: preserving named script bindings may make sense, but that does not necessarily justify changing arguments back to an object.

  11. fjtirado commented on Sep 28, 2026

    @fjtirado
    CollaboratorAuthor

    I agree,
    For shell, argument should be a list,
    For scripts, that usually support named args,we should use a map.

  12. cdavernas commented on Sep 28, 2026

    @cdavernas
    Collaborator

    @fjtirado I re-read our Slack PMs, and I believe you're right - that is indeed what we had settled on.
    It also further specializes the script task, which would otherwise be little more than a shorthand for a shell task.

  13. added a commit that references this issue on Sep 28, 2026
    fe69b1b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area: specChanges in the Specificationchange: fixSomething isn't working. Impacts in a minor version change.type: bug

Type

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions