Skip to content

[Bug] lean live command fails on Linux when payload contains $type due to shell expansion #633

@JanMachacek1

Description

@JanMachacek1

Description

When sending a live command via lean live command <project> --data <payload>, the command silently fails on Linux if the JSON payload contains the $type key.

The issue occurs because lean-cli uses subprocess.run(..., shell=True) with double quotes ("...") to execute the docker exec command writing the payload to the container. On Unix-like systems, the host shell (/bin/sh) evaluates $type as an environment variable before passing the command to Docker, replacing it with an empty string.

Steps to Reproduce

  1. On a Linux or macOS machine, run a live algorithm in a Docker container.
  2. Attempt to send a command requiring the $type property:
    lean live command MyProject --data '{"$type": "MyCustomCommand", "Quantity": 10}'
  3. The command will fail. The algorithm logs will show it received an invalid command (e.g., {"": "MyCustomCommand", "Quantity": 10} because $type evaluated to empty).

Technical Details & Root Cause

In lean.components.docker.docker_manager.py:write_to_file(), the command is constructed as follows:

data = dumps(data, cls=DecimalEncoder)
data = data.replace('"','\\"')
command = f'docker exec {docker_container_name} bash -c "echo \'{data}\' > {docker_file.as_posix()}"'
try:
    run(command, shell=True, check=True)
  1. The --data argument is evaluated and dumped back into a JSON string using json.dumps().
  2. All double quotes " are replaced with \".
  3. The command string wraps the echo statement inside double quotes (bash -c "echo ...") and executes it via shell=True.

Because json.dumps() guarantees an even number of backslashes, passing \$type via the terminal doesn't work (Python parses the backslash out, or dumps adds a second one \\$type). Consequently, the host's /bin/sh sees "$type" unescaped and expands it.

(Note: This bug does not affect Windows, as cmd.exe does not use the $ syntax for environment variables).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions