Skip to content

--json flag rejects valid JSON when string values contain \n escapes #22

Description

@sud0n1m

The --json flag (both inline and @filename) rejects perfectly valid JSON whenever a string value decodes to a character including U+000A, even when the JSON source uses the spec-compliant \n escape.

Repro

# Build a valid JSON file using Python's json.dumps (newline escaped as \n)
python3 -c 'import json; open("/tmp/escaped.json","w").write(json.dumps({"id":"x","name":"x","type":"COMPONENT","settings":{},"parts":{"html":"line1\nline2"}}))'

# Python parses it without issue — confirming the JSON is well-formed
python3 -c 'import json; print(json.load(open("/tmp/escaped.json")))'
# → {'id': 'x', ..., 'parts': {'html': 'line1\nline2'}}

# cio rejects it
cio api /v1/environments/216574/ds/nodes -X POST --json @/tmp/escaped.json --dry-run
# → {"error":true,"code":"VALIDATION_ERROR","message":"JSON string value contains control character at position 5 (U+000A) (from file /tmp/escaped.json)","details":{"flag":"--json"}}

Per RFC 8259 §7, \n inside a string is the correct way to encode a literal newline. The CLI is validating the decoded string value for control chars rather than the JSON source, which makes it impossible to pass HTML, Carta markup, or any other multi-line content via --json without first collapsing newlines to spaces.

Expected

Treat input as valid JSON whenever it parses as valid JSON. If there's a security/safety concern with raw control chars hitting downstream APIs, surface it as a warning or add an explicit opt-in flag (--trust-json or --no-control-char-check), but don't break valid JSON by default.

Workaround (current)

Collapse HTML / multi-line content to a single line before passing to --json. This is what the in-app and Design Studio workflows have to do today.

Confirmed on @customerio/cli@0.0.5 (latest as of 2026-05-14).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions