{"record":{"id":"d01df618c7438983","repo":"iOfficeAI/OfficeCLI","slug":"expected-propertyname","errorCode":null,"errorMessage":"Expected PropertyName","messagePattern":"Expected PropertyName","errorType":"validation","errorClass":"JsonException","httpStatus":null,"severity":"warning","filePath":"src/officecli/BatchTypes.cs","lineNumber":81,"sourceCode":"        writer.WriteEndObject();\n    }\n}\n\ninternal class BatchItemConverter : JsonConverter<BatchItem>\n{\n    private static readonly LenientStringDictionaryConverter PropsConverter = new();\n\n    public override BatchItem? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n    {\n        if (reader.TokenType != JsonTokenType.StartObject)\n            throw new JsonException(\"Expected StartObject for BatchItem\");\n\n        var item = new BatchItem();\n        while (reader.Read())\n        {\n            if (reader.TokenType == JsonTokenType.EndObject) return item;\n            if (reader.TokenType != JsonTokenType.PropertyName)\n                throw new JsonException(\"Expected PropertyName\");\n            var prop = reader.GetString()!;\n            reader.Read();\n            switch (prop.ToLowerInvariant())\n            {\n                case \"command\":\n                case \"op\":\n                    item.Command = reader.GetString() ?? \"\";\n                    break;\n                case \"path\": item.Path = reader.GetString(); break;\n                case \"parent\": item.Parent = reader.GetString(); break;\n                case \"type\": item.Type = reader.GetString(); break;\n                case \"from\": item.From = reader.GetString(); break;\n                case \"index\": item.Index = reader.TokenType == JsonTokenType.Null ? null : reader.GetInt32(); break;\n                case \"after\": item.After = reader.GetString(); break;\n                case \"before\": item.Before = reader.GetString(); break;\n                case \"to\": item.To = reader.GetString(); break;\n                case \"path2\": item.Path2 = reader.GetString(); break;\n                case \"props\": item.Props = PropsConverter.Read(ref reader, typeof(Dictionary<string, string>), options); break;","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/BatchTypes.cs#L63-L99","documentation":"JsonException from BatchItemConverter.Read inside the item loop: after reading a property value, the next token was not a PropertyName. This signals a structurally malformed BatchItem object (a value appearing where a key is expected), distinct from error 18 (whole element not an object) and error 15 (props sub-object malformed).","triggerScenarios":"A batch item like {\"command\":\"set\" \"path\":\"/A1\"} (missing comma), {\"command\":\"set\", \"path\":\"/A1\" \"extra\"} (key with no value then a bare token), or any broken key/value sequence inside a BatchItem.","commonSituations":"Hand-built or templated JSON missing commas/colons; a serializer bug emitting values back-to-back; partial JSON pasted from docs.","solutions":["Re-serialize batch items with a real JSON serializer so structure is guaranteed.","Lint/parse the batch JSON before sending to catch structural errors early.","Ensure each item is \"key\": value pairs, comma-separated, inside braces."],"exampleFix":"// before: [{ command:'set' path:'/A1' props:{text:'x'} }]  // missing commas\n// after:  const items = [{ command:'set', path:'/A1', props:{ text:'x' } }];\nawait doc.batch(items);","handlingStrategy":"validation","validationCode":"// Round-trip the entire batch through a parser to catch structural errors\ntry { JSON.parse(JSON.stringify(items)); } catch (e) { throw new Error('Malformed batch: ' + e.message); }\nawait doc.batch(items);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Construct batch items as JS objects and let JSON.stringify handle structure.","Validate payload structure before sending.","Avoid copy-pasting partial JSON examples."],"tags":["batch","json","batch-item","malformed","deserialization"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}