Skip to main content
← Back to list
01Issue
BugShippedSwamp CLI
Assigneesstack72

#244 global-arg silently strips unknown keys; should reject via strict Zod schema

Opened by bixu · 5/5/2026· Shipped 5/5/2026

Summary

--global-arg accepts unknown keys without warning. Typos and unsupported syntax (like array indices) silently disappear, leaving users with broken models that "succeeded" on creation. Migrating the global-arguments Zod schema to .strict() would surface these as validation errors.

Reproduction

Tested on swamp 20260504.162725.0-sha.51f43769.

A model whose globalArguments Zod schema declares a volumes field (array of {host, guest} objects):

# Typo — silently dropped, no error, no warning
swamp model create @hivemq/apple_container m \
  --global-arg containerName=m \
  --global-arg image=docker.io/library/debian:12-slim \
  --global-arg "volumesss=whatever"

# Bracket array syntax — looks like it should work, also silently dropped
swamp model create @hivemq/apple_container m \
  --global-arg containerName=m \
  --global-arg image=docker.io/library/debian:12-slim \
  --global-arg "volumes[0].host=/tmp/x" \
  --global-arg "volumes[0].guest=/workspace"

# Result for both: command exits 0, model YAML on disk has no `volumes`
# field. The downstream `up` method fails or runs without the bind mount,
# and the user has to debug why.

For contrast, dotted-array syntax does produce a clean validation error:

--global-arg "volumes.0.host=/tmp/x"
# error: volumes: Invalid input: expected array, received object  ✓ helpful

Root cause

Two things compound:

  1. src/cli/input_parser.ts:39-58setNestedValue splits the key on . only and always materializes intermediate path segments as objects. So volumes[0].host{ "volumes[0]": { host: "..." } } (literal key with brackets), and volumes.0.host{ volumes: { "0": { host: "..." } } } (object, not array).
  2. src/libswamp/models/create.ts:163modelDef.globalArguments.safeParse(...) uses default Zod object behavior, which strips unknown keys silently. So the literal volumes[0] key is filtered out and the rest of the input passes validation.

The first issue (no [N] syntax in the parser) is its own discussion — adding array support would help, but it's not the immediate ask here.

The second issue is the higher-leverage fix: any unknown key, whether from a typo, an old field name, or unsupported syntax, should fail loudly.

Proposed fix

Change the global-arguments validation call to reject unknown keys. Either:

  • Use Zod's .strict() on the schema before parsing: modelDef.globalArguments.strict().safeParse(globalArguments)
  • Or wrap with a check that compares input keys to schema keys and emits a validation error for any extras, ideally with a "did you mean…" suggestion.

Same fix likely applies to method-input validation (parseKeyValueInputs flows into method args via the same setNestedValue path).

Environment

  • swamp 20260504.162725.0-sha.51f43769
  • macOS 25.4.0 (Darwin arm64)
  • Reproduced against @hivemq/apple_container (custom extension; behavior is schema-agnostic — any model with a non-trivial globalArguments schema reproduces it)

Impact

Real bug encountered while building the swampbox wrapper for PLT-479. The script's swamp model create ... --global-arg "volumes[0].host=$PWD" ... silently produced a model without a workspace mount, requiring a post-create YAML edit as a workaround. Without strict validation, every consumer of --global-arg is exposed to the same class of silent failure on any typo.

02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 3 MORETRIAGE+ 7 MOREREVIEW+ 5 MOREPR_MERGEDSHIPPED

Shipped

5/5/2026, 6:27:05 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 assigned stack725/5/2026, 5:13:48 PM

Sign in to post a ripple.