windmill-labs/windmill · error · Error

--arg '${spec}' must be <script>:<param>=<json-or-string>

Error message

--arg '${spec}' must be <script>:<param>=<json-or-string>

What it means

Syntax validation in parseArgBinding: the --arg spec doesn't match <script>:<param>=<json-or-string>. Unlike --upload, the :<param> part is mandatory (there is no single-S3Object convention to infer the param from), so a spec missing the ':' or '=' — or with an empty script/param — triggers this. The input at fault is the --arg string as typed.

Source

Thrown at cli/src/commands/pipeline/pipelineUpload.ts:50

export type ArgBinding = { scriptTok: string; param: string; value: unknown };

/**
 * Parse an `--arg` spec: `<script>:<param>=<value>`. Split on the FIRST `=`
 * (values may contain `=`); the value is JSON when it parses as JSON, else the
 * raw string — so `stats:limit=10` is a number and
 * `daily_report:partition=2026-07-02` a string. `:<param>` is required: unlike
 * `--upload` there is no single-S3Object convention to infer it from.
 */
export function parseArgBinding(spec: string): ArgBinding {
  const eq = spec.indexOf("=");
  const left = eq < 0 ? "" : spec.slice(0, eq).trim();
  const raw = eq < 0 ? "" : spec.slice(eq + 1).trim();
  const colon = left.indexOf(":");
  const scriptTok = colon < 0 ? "" : left.slice(0, colon).trim();
  const param = colon < 0 ? "" : left.slice(colon + 1).trim();
  if (!scriptTok || !param) {
    throw new Error(`--arg '${spec}' must be <script>:<param>=<json-or-string>`);
  }
  let value: unknown;
  try {
    value = JSON.parse(raw);
  } catch {
    value = raw;
  }
  return { scriptTok, param, value };
}

/**
 * Names of a schema's S3Object properties. The resource name in `format`
 * varies by language parser — TS/python emit `resource-s3_object`, the SQL
 * dialects emit `resource-S3Object` — so match it case/underscore-insensitively
 * the way the frontend's ArgInput does.
 */
export function s3ObjectParams(schema: any): string[] {
  const props = schema?.properties ?? {};

View on GitHub (pinned to e474e8803c)

Solutions

  1. Include all three parts: --arg myscript:limit=10
  2. Quote values containing '=' or special characters so the first '=' split lands correctly
  3. JSON-quote structured values: --arg s:cfg='{\"k\":1}'
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at cli/src/commands/pipeline/pipelineUpload.ts:50 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/ca983f9b8bafbd9a. Report an issue: GitHub.