{"record":{"id":"a9477079b3989cc0","repo":"larksuite/cli","slug":"expected-object-got-v","errorCode":null,"errorMessage":"expected object, got %v","messagePattern":"expected object, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/schema/types.go","lineNumber":156,"sourceCode":"\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"marshal value for %q: %w\", k, err)\n\t\t}\n\t\tbuf.Write(valJSON)\n\t}\n\tbuf.WriteByte('}')\n\treturn buf.Bytes(), nil\n}\n\n// UnmarshalJSON parses an object preserving key order via json.Decoder.Token().\n// Used for round-tripping in tests (and future golden update flows).\nfunc (o *OrderedProps) UnmarshalJSON(data []byte) error {\n\tdec := json.NewDecoder(bytes.NewReader(data))\n\ttok, err := dec.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif delim, ok := tok.(json.Delim); !ok || delim != '{' {\n\t\treturn fmt.Errorf(\"expected object, got %v\", tok)\n\t}\n\to.Order = nil\n\to.Map = make(map[string]Property)\n\tfor dec.More() {\n\t\tkeyTok, err := dec.Token()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tkey, ok := keyTok.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"expected string key, got %v\", keyTok)\n\t\t}\n\t\tvar prop Property\n\t\tif err := dec.Decode(&prop); err != nil {\n\t\t\treturn err\n\t\t}\n\t\to.Order = append(o.Order, key)\n\t\to.Map[key] = prop","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/schema/types.go#L138-L174","documentation":"OrderedMap.UnmarshalJSON uses a streaming json.Decoder and requires the input to begin with a '{' object token so it can preserve key order. If the first token is anything else (array, string, number, boolean, null), this error is returned.","triggerScenarios":"Calling json.Unmarshal into an OrderedMap (or Property containing one) with JSON input like \"[]\", \"\\\"str\\\"\", \"123\", \"true\", or \"null\" instead of an object.","commonSituations":"API response shape changed from object to array or scalar; feeding a JSON fragment into the wrong field; unmarshaling an empty/null payload where an object schema was expected.","solutions":["Ensure the JSON input is an object starting with '{'","Log/inspect the raw payload before unmarshaling to verify its shape","Pre-validate the first non-whitespace byte is '{' before calling Decode"],"exampleFix":"// before\ndata := []byte(`[]`)\njson.Unmarshal(data, &om) // expected object, got [\n// after\ndata := []byte(`{\"a\":{}}`)\njson.Unmarshal(data, &om)","handlingStrategy":"validation","validationCode":"trimmed := bytes.TrimLeft(raw, \" \\t\\r\\n\")\nif len(trimmed) == 0 || trimmed[0] != '{' {\n\treturn errors.New(\"payload is not a JSON object\")\n}\nerr := json.Unmarshal(raw, &om)","typeGuard":null,"tryCatchPattern":"if err := json.Unmarshal(data, &om); err != nil {\n\tif strings.Contains(err.Error(), \"expected object\") {\n\t\t// payload is not an object: log raw data and recover with defaults\n\t}\n\treturn err\n}","preventionTips":["Verify API response shapes before decoding into OrderedMap","Handle null/empty payloads explicitly upstream","Pin/validate API contract with schema checks"],"tags":["json","unmarshal","schema","type-mismatch"],"backgroundTag":"json-type-mismatch","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}