{"record":{"id":"ab184eed1c39f9aa","repo":"iOfficeAI/OfficeCLI","slug":"corrupt-batch-ab184e","errorCode":"corrupt_batch","errorMessage":"Dump-reader plugin '{plugin.Manifest.Name}' emitted a JSON array; protocol v1 requires JSONL (one BatchItem per line).","messagePattern":"Dump-reader plugin '(.+?)' emitted a JSON array; protocol v1 requires JSONL \\(one BatchItem per line\\)\\.","errorType":"exception","errorClass":"CliException","httpStatus":null,"severity":"error","filePath":"src/officecli/Core/Plugins/DumpReaderInvoker.cs","lineNumber":88,"sourceCode":"        var bufferedLines = new List<string>();\n\n        try\n        {\n            void OnLine(string raw)\n            {\n                // Strip a per-line UTF-8 BOM (U+FEFF). Some Windows JSON\n                // serializers emit BOM on every line of JSONL output, which\n                // is technically RFC 8259 noncompliant but easy to absorb at\n                // the host. Trim handles trailing whitespace and CR from a\n                // CRLF-on-Windows plugin.\n                var line = raw.TrimStart('﻿').Trim();\n                if (line.Length == 0) return;\n\n                // Reject legacy top-level JSON arrays explicitly. Plugins that\n                // emitted `[...]` under the old protocol now fail with a clear\n                // error instead of being parsed as a malformed BatchItem.\n                if (line[0] == '[')\n                    throw new CliException(\n                        $\"Dump-reader plugin '{plugin.Manifest.Name}' emitted a JSON array; protocol v1 requires JSONL (one BatchItem per line).\")\n                    { Code = \"corrupt_batch\" };\n\n                // Buffer raw line; defer JSON parse + replay to the\n                // main-thread loop after plugin exit. JSON parse errors\n                // surface there with the same item-index semantics.\n                bufferedLines.Add(line);\n            }\n\n            var idle = plugin.Manifest.ResolveIdleTimeout(\"dump\");\n            var result = PluginProcess.Run(new PluginProcess.RunOptions\n            {\n                ExecutablePath = plugin.ExecutablePath,\n                Arguments = new[] { \"dump\", sourceFullPath },\n                IdleTimeoutSeconds = idle,\n                OnStdoutLine = OnLine,\n            });\n","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Core/Plugins/DumpReaderInvoker.cs#L70-L106","documentation":"CliException (code 'corrupt_batch') thrown when a dump-reader plugin's stdout line begins with '[' — i.e. a top-level JSON array. Protocol v1 requires JSONL: exactly one BatchItem JSON object per line. The check runs in the per-line OnLine callback after BOM/whitespace trimming.","triggerScenarios":"A plugin built against the legacy protocol emits `[{...},{...}]` as a single JSON array. Any line whose first char is '[' trips it.","commonSituations":"Upgrading the host to protocol v1 while the plugin still targets v0; a plugin author serializing a List<BatchItem> with one JsonSerializer.Serialize call instead of per-item writes.","solutions":["Update the plugin to emit one BatchItem per line (jsonl), e.g. foreach item: Console.WriteLine(JsonSerializer.Serialize(item)).","Pin or upgrade the plugin to a version matching protocol v1.","Confirm the plugin is not wrapping output in an array and is flushing each line."],"exampleFix":"// before (plugin, v0)\nvar json = JsonSerializer.Serialize(allItems);\nConsole.WriteLine(json);\n\n// after (plugin, v1)\nforeach (var item in allItems)\n    Console.WriteLine(JsonSerializer.Serialize(item));","handlingStrategy":"validation","validationCode":"// In the plugin: validate output is JSONL before exiting.\nforeach (var line in emitted) if (line.TrimStart().StartsWith(\"[\"))\n    throw new InvalidOperationException(\"Output is a JSON array; emit JSONL.\");","typeGuard":null,"tryCatchPattern":"try { DumpReaderInvoker.Run(source, ext); }\ncatch (CliException ex) when (ex.Code == \"corrupt_batch\")\n{ /* plugin emits JSON arrays — upgrade/rebuild the plugin */ }","preventionTips":["Add a JSONL conformance test to plugin CI.","Never wrap batch output in a top-level array.","Pin plugin and host to the same protocol major version."],"tags":["plugins","dump-reader","jsonl","protocol","cli-exception"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}