Skip to content

Inconsistent argument feed to IoT Core Jobs #529

@mbenencase

Description

@mbenencase

Describe the bug

I have a script in my IoT Device (Ubuntu 20.04 OS ARM64) that receives the first argument as the tag of our Docker image that must run on the device.

The problem that I was facing is that I've created the following job according to AWS templates:

{
  "version": "1.0",
  "steps": [
    {
      "action": {
        "name": "Update-Docker-Image",
        "type": "runHandler",
        "input": {
          "handler": "update-software-image",
          "args": [
            "2025-11-26-2492ea5"
          ],
          "path": "/usr/local/bin/iot-jobs-handlers"
        },
        "runAsUser": "root"
      }
    }
  ]
}

And looking that the client in my device I saw the following:

Dec 03 17:54:18 qcs6490-odk25 aws-iot-device-client[792]: 2025-12-03T17:54:18.649Z [INFO]  {JobEngine.cpp}: About to execute step with name: Update-Docker-Image
Dec 03 17:54:18 qcs6490-odk25 aws-iot-device-client[792]: 2025-12-03T17:54:18.650Z [DEBUG] {JobEngine.cpp}: Using path {/usr/local/bin/iot-jobs-handlers} supplied by job document for command execution
Dec 03 17:54:18 qcs6490-odk25 aws-iot-device-client[792]: 2025-12-03T17:54:18.650Z [INFO]  {JobEngine.cpp}: About to execute: /usr/local/bin/iot-jobs-handlers/update-software-image root 2025-11-26-2492ea5

In my update-software-image shell script I logged what was the first argument that it was receiving:

2025-12-03 17:52:11 UTC Pulling Docker Tag: root

So the username root was being sent as the first argument to the shell script during execution. To solve this from my side is trivial, I just set the docker image tag as the second argument.

To Reproduce

Steps to reproduce the behavior:

  1. Install the version Device Client at commit: 7d8db29
  2. Create a Job that receives an argument. Example:
{
  "version": "1.0",
  "steps": [
    {
      "action": {
        "name": "Update-Docker-Image",
        "type": "runHandler",
        "input": {
          "handler": "update-docker-image",
          "args": [
            "2025-11-26-2492ea5"
          ],
          "path": "/usr/local/bin/iot-jobs-handlers"
        },
        "runAsUser": "root"
      }
    }
  ]
}

Example of the shell script in the device:

#!/bin/sh
set -e

log() {
    echo "$(date +"%Y-%m-%d %H:%M:%S %Z") $*" >> "$LOG_FILE"
}

TAG="$1"

log "Received tag: $TAG"
exit 0

Expected behavior

I was expecting that the arguments list present in the args field of the Job JSON would be passed as they appear in order. Also, I wasn't expecting that the runAsUser parameter would appear in the job execution.

Actual behavior

Currently, it provides the runAsUser parameter as the first parameter of the job execution and the list of arguments present in args field are passed starting at the second position.

Example:

{
  "version": "1.0",
  "steps": [
    {
      "action": {
        "name": "Update-Docker-Image",
        "type": "runHandler",
        "input": {
          "handler": "update-docker-image",
          "args": [
            "2025-11-26-2492ea5"
          ],
          "path": "/usr/local/bin/iot-jobs-handlers"
        },
        "runAsUser": "root"
      }
    }
  ]
}

will make the job to be executed (in the IoT Device) as:

/usr/local/bin/iot-jobs-handlers root 2025-11-26-2492ea5

I.e. the root parameter (the user) appears as part of the arguments list of the shell script.

Environment (please complete the following information):

Additional context
Nothing to add.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions