Skip to main content
← Back to list
01Issue
FeatureClosedSwamp CLI
AssigneesNone

#315 swamp model create --global-arg KEY=VALUE doesn't coerce strings to z.number() schemas

Opened by stack72 · 5/11/2026

Summary

swamp model create <type> <name> --global-arg KEY=VALUE always passes the value through as a string. When the model's globalArguments schema declares a numeric field with plain z.number(), the zod validator rejects it with expected number, received string and model creation fails.

There is no way from the CLI to inject a non-string value for --global-arg — JSON / typed payloads only exist for model method run --input.

Reproducer

// extensions/models/repro/repro.ts
import { z } from "npm:[email protected]";
import { defineModel } from "...";

const GlobalArgsSchema = z.object({
  cpus: z.number().int().positive().default(4),
});

export const model = defineModel({
  name: "@example/repro",
  globalArguments: GlobalArgsSchema,
  // ...
});
$ swamp model create "@example/repro" demo --global-arg "cpus=4" --json
{
  "error": "Invalid global arguments for type '@example/repro':\n  cpus: Invalid input: expected number, received string"
}

Expected

Either:

  1. The CLI parses bare numeric / boolean / JSON-ish values and passes them as the inferred type, or
  2. The CLI coerces strings to the schema's declared primitive type before validation (effectively wrapping every leaf scalar in z.coerce.*).

Today, extension authors have to opt into z.coerce.number() / z.coerce.boolean() everywhere a CLI user might set the field — and the CLI ergonomics depend on the schema, which is leaky.

Workaround

Use z.coerce.number() (and z.coerce.boolean() etc.) in the extension's globalArguments schema. Discovered while building @hivemq/mudroom — the wrapper's swamp model create ... --global-arg cpus=4 --global-arg memoryMib=4096 was silently failing for first-time users (and in CI), and the underlying failure was hidden because the wrapper redirects swamp ... --json >/dev/null (since the success-path stdout is just the JSON envelope).

Impact

  • First-time UX: any extension whose globalArguments has numeric/boolean fields is broken from the CLI unless the author knows to use z.coerce.*.
  • Wrapper authors: error messages get swallowed by >/dev/null of --json stdout, which makes the failure mode confusing.

References


Automoved by swampadmin from https://github.com/systeminit/swamp/issues/1357

02Bog Flow
OPENTRIAGEDIN PROGRESSCLOSED

Closed

5/11/2026, 1:04:01 PM

No activity in this phase yet.

03Sludge Pulse
Editable. Press Enter to edit.

stack72 commented 5/11/2026, 12:49:22 PM

Dupe of #316

Sign in to post a ripple.