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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions