{"record":{"id":"33b02cc1c8d06291","repo":"charmbracelet/crush","slug":"s-s-expects-valid-json-got-q-s","errorCode":null,"errorMessage":"%s: --%s expects valid JSON, got %q: %s","messagePattern":"(.+?): --(.+?) expects valid JSON, got %q: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/shellconfig/flags.go","lineNumber":173,"sourceCode":"\tcase flagJSONObject:\n\t\tv, err := nextArg(args, i, name)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\tvar object map[string]any\n\t\tif err := json.Unmarshal([]byte(v), &object); err != nil || object == nil {\n\t\t\treturn nil, 0, fmt.Errorf(\"%s: --%s expects a JSON object, got %q\", args[0], name, v)\n\t\t}\n\t\treturn object, i + 2, nil\n\n\tcase flagJSONAny:\n\t\tv, err := nextArg(args, i, name)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\tvar parsed any\n\t\tif err := json.Unmarshal([]byte(v), &parsed); err != nil {\n\t\t\treturn nil, 0, fmt.Errorf(\"%s: --%s expects valid JSON, got %q: %s\", args[0], name, v, err)\n\t\t}\n\t\treturn parsed, i + 2, nil\n\n\tdefault:\n\t\treturn nil, 0, fmt.Errorf(\"%s: --%s has unknown flag kind\", args[0], name)\n\t}\n}\n\n// nextArg returns args[i+1], erroring if the flag is missing its value.\nfunc nextArg(args []string, i int, flag string) (string, error) {\n\tif i+1 >= len(args) {\n\t\treturn \"\", fmt.Errorf(\"%s: --%s requires a value\", args[0], flag)\n\t}\n\treturn args[i+1], nil\n}\n\n// storeFlag writes a parsed value into target according to spec.op.\nfunc storeFlag(target map[string]any, spec flagSpec, val any) {","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/shellconfig/flags.go#L155-L191","documentation":"This error is thrown by parseFlagValue when a flag declared with kind flagJSONAny receives a value that fails json.Unmarshal. Unlike flagJSONObject, any JSON type is accepted (object, array, string, number, bool), but the text must be syntactically valid JSON. The underlying encoding/json error message is appended to help pinpoint the syntax problem.","triggerScenarios":"Calling a builtin flag that parses arbitrary JSON (flagJSONAny) with malformed text such as unquoted keys (`{a:1}`), single-quoted strings, unquoted bare words (`foo`), trailing commas, unterminated strings/brackets, or a value the shell partially mangled before it reached the parser.","commonSituations":"Single quotes inside the JSON conflicting with shell quoting; forgetting that bare words are not JSON (need `\"foo\"`); copying JSON5/YAML into a JSON flag; Windows cmd where quoting rules differ and inner double quotes get stripped.","solutions":["Pipe the value through `jq .` locally to confirm it is valid JSON before passing it.","Use single quotes around the whole JSON value on POSIX shells so double quotes survive.","Quote all keys and strings and remove trailing commas; convert YAML/JSON5 to strict JSON.","Read the appended json error (offset/position) to locate the exact syntax problem."],"exampleFix":"// before\noptions set --data '{\"model\": claude-3,}'\n// after\noptions set --data '{\"model\": \"claude-3\"}'","handlingStrategy":"validation","validationCode":"echo \"$value\" | jq -e . >/dev/null 2>&1 || { echo \"flag value is not valid JSON\" >&2; exit 2; }","typeGuard":"func isJSON(s string) bool {\n    var v any\n    return json.Unmarshal([]byte(s), &v) == nil\n}","tryCatchPattern":"if err := applyFlags(specs, args, start, target, cmd, stderr); err != nil {\n    if strings.Contains(err.Error(), \"expects valid JSON\") {\n        // err embeds the json.Syntax/Unmarshal message; print as-is with hint\n        fmt.Fprintln(stderr, err, \"\\nHint: quote the value and validate with 'jq .'\")\n    }\n    return err\n}","preventionTips":["Round-trip check with `jq .` before invoking the command.","Use single quotes on POSIX shells; on Windows cmd escape inner double quotes.","Convert YAML/JSON5 input to strict JSON first (all keys quoted, no trailing commas).","Never pass bare unquoted words; even strings need JSON quotes: \"foo\"."],"tags":["cli","json","argument-parsing","shell-config"],"backgroundTag":"invalid-json","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}