dagger/dagger · error · InvalidInputError

Unable to decode input argument '{arg_name}'

Error message

Unable to decode input argument '{arg_name}'

What it means

When invoking a function, each input argument arrives as a JSON-encoded value. If json.loads fails for a specific argument, invoke() raises InvalidInputError naming the argument and attaching the raw value as extra, because the function cannot be called without correctly decoded inputs.

Source

Thrown at sdk/python/src/dagger/mod/_module.py:323

                raise InvalidInputError(msg, extra=extra) from e

        inputs = {}
        for arg in input_args:
            # NB: These are already loaded by `input_args`,
            # the await just returns the cached value.
            arg_name = await arg.name()
            arg_value = await arg.value()
            try:
                # Cattrs can decode JSON strings but use `json` directly
                # for more granular control over the error.
                inputs[arg_name] = json.loads(arg_value)
            except ValueError as e:
                logger.exception("Failed to decode JSON input value")
                msg = f"Unable to decode input argument '{arg_name}'"
                extra = {
                    "json_value": arg_value,
                }
                raise InvalidInputError(msg, extra=extra) from e

        if logger.isEnabledFor(logging.DEBUG):
            logger.debug(
                "invoke => %s",
                {
                    "parent_name": parent_name,
                    "parent_json": textwrap.shorten(parent_json, 144),
                    "name": name,
                    "input_args": textwrap.shorten(repr(inputs), 144),
                },
            )

        result = await self.get_result(
            parent_name,
            parent_state,
            name,
            inputs,
        )

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Inspect the json_value in the error's extra to see the malformed payload for that argument.
  2. Quote/escape the argument on the CLI (e.g. `dagger call fn --arg '{"a":1}'` with correct shell quoting).
  3. Ensure the value is strict JSON (double quotes, no trailing commas, no single quotes).
  4. Align caller and module SDK versions; validate inputs with a JSON linter before invoking.

Example fix

// before (shell)
dagger call greet --name 'world's'   # bad quoting -> invalid JSON

// after (shell)
dagger call greet --name "world's"
Defensive patterns

Strategy: validation

Validate before calling

import json

def validate_arg(name: str, raw: str) -> None:
    try:
        json.loads(raw)
    except ValueError as e:
        raise ValueError(f"argument '{name}' is not valid JSON: {raw!r}") from e

Try / catch

try:
    result = await module.invoke()
except InvalidInputError as e:
    logger.error("bad argument payload: %s | value=%r", e, e.extra.get("json_value"))
    raise

Prevention

When it happens

Trigger: The engine (or a caller via `dagger call`) passes a value for argument {arg_name} that is not valid JSON — e.g. unquoted shell input like `--num abc` handled elsewhere but raw strings with bad quoting, or a caller SDK serializing incorrectly.

Common situations: Passing shell strings with special characters/unbalanced quotes to `dagger call --arg`; caller SDK version mismatch producing malformed payloads; JSON5-style input (trailing commas, single quotes) that strict json.loads rejects; piping truncated values.

Understand the failure class

Related errors


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/5d3235cf905c3456. Report an issue: GitHub.