{"record":{"id":"ed33e2fea50d2434","repo":"charmbracelet/crush","slug":"s-s-expects-a-json-object-got-q","errorCode":null,"errorMessage":"%s: --%s expects a JSON object, got %q","messagePattern":"(.+?): --(.+?) expects a JSON object, got %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/shellconfig/flags.go","lineNumber":162,"sourceCode":"\t\tif err != nil {\n\t\t\treturn nil, 0, fmt.Errorf(\"%s: --%s expects a number, got %q\", args[0], name, v)\n\t\t}\n\t\treturn f, i + 2, nil\n\n\tcase flagKeyValue:\n\t\tif i+2 >= len(args) {\n\t\t\treturn nil, 0, fmt.Errorf(\"%s: --%s requires a key and value\", args[0], name)\n\t\t}\n\t\treturn [2]string{args[i+1], args[i+2]}, i + 3, nil\n\n\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}","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/shellconfig/flags.go#L144-L180","documentation":"This error is thrown by parseFlagValue when a flag declared with kind flagJSONObject receives a value that is not valid JSON or does not unmarshal into a JSON object (map[string]any). The check `err != nil || object == nil` also rejects bare `null` and, because the target type is a map, any array, string, number, or boolean. It exists so flags like --provider-options only accept object-shaped JSON that can be merged into a child map.","triggerScenarios":"Calling a builtin flag like --provider-options with a value that is invalid JSON (e.g. `{api_key: x}` with unquoted keys, single quotes, trailing commas), a JSON array (`[1,2]`), a bare scalar (`\"foo\"`, `42`, `true`), or the literal `null`.","commonSituations":"Hand-writing provider options with unquoted keys or Python-style True/False; shell stripping double quotes (typing --provider-options '{\"a\":1}' without proper quoting so the shell eats braces/quotes); passing a JSON array where an object is expected; copying JSON with trailing commas.","solutions":["Validate the value parses as a JSON object first: `echo '<value>' | jq -e 'type == \"object\"'`.","Quote the entire JSON blob in single quotes so the shell does not strip braces or double quotes.","Use double quotes for all JSON keys and string values, no trailing commas: `'{\"temperature\": 0.5}'`.","If passing non-object JSON, use the appropriate flag that accepts arbitrary JSON instead of the object-typed flag."],"exampleFix":"// before\nprovider add x --provider-options '{temperature: 0.5,}'\n// after\nprovider add x --provider-options '{\"temperature\": 0.5}'","handlingStrategy":"validation","validationCode":"echo \"$value\" | jq -e 'type == \"object\"' >/dev/null || { echo \"flag value must be a JSON object\" >&2; exit 2; }","typeGuard":"func isJSONObject(s string) bool {\n    var m map[string]any\n    return json.Unmarshal([]byte(s), &m) == nil && m != nil\n}","tryCatchPattern":"if err := applyFlags(specs, args, start, target, cmd, stderr); err != nil {\n    if strings.Contains(err.Error(), \"expects a JSON object\") {\n        fmt.Fprintln(stderr, \"Value must be a JSON object like '{\\\"key\\\": 1}', not an array or scalar\")\n    }\n    return err\n}","preventionTips":["Validate with jq (type == \"object\") before passing the value.","Single-quote the entire JSON blob so the shell preserves braces and double quotes.","Remember null is rejected too — a JSON object must have at least {} shape.","Prefer repeated simple flags over hand-written JSON when available."],"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"}