{"record":{"id":"e291626e846f553c","repo":"iOfficeAI/OfficeCLI","slug":"unsupported-cell-property-string-join-cell","errorCode":null,"errorMessage":"Unsupported cell property: {string.Join(\"; \", cellHintMessages)}","messagePattern":"Unsupported cell property: (.+?)","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs","lineNumber":914,"sourceCode":"                ?? properties.GetValueOrDefault(\"image.alt\");\n            if (inCellAlt != null) Core.ParseHelpers.ValidateXmlText(inCellAlt, \"alt\");\n            SetInCellImage(cell, inCellImg, inCellAlt);\n        }\n\n        // CONSISTENCY(cell-prop-hints): mirror Set's CellPropHints check\n        // here. Before the style filter runs, flag any ambiguous flat\n        // keys (e.g. `color` — is it font.color or fill?) as unsupported.\n        // Without this, Add silently drops the key while Set loudly\n        // rejects it — inconsistent, and the caller's intent is lost.\n        var cellHintMessages = new List<string>();\n        foreach (var (key, _) in properties)\n        {\n            var hint = CellPropHints.TryGetHint(key);\n            if (hint != null)\n                cellHintMessages.Add(hint);\n        }\n        if (cellHintMessages.Count > 0)\n            throw new ArgumentException(\n                \"Unsupported cell property: \" + string.Join(\"; \", cellHintMessages));\n\n        // Apply style properties if any. Use TryGetValue per key so the\n        // TrackingPropertyDictionary comparer marks each style key as\n        // accessed — bare foreach over the upcast Dictionary<,> base type\n        // bypasses the recording GetEnumerator override and leaves\n        // legitimately-consumed keys (bold, align, color, ...) reported\n        // as UNSUPPORTED while their values silently take effect.\n        var cellStyleProps = new Dictionary<string, string>();\n        foreach (var key in properties.Keys.ToList())\n        {\n            if (ExcelStyleManager.IsStyleKey(key) && properties.TryGetValue(key, out var val))\n                cellStyleProps[key] = val;\n        }\n        if (cellStyleProps.Count > 0)\n        {\n            var cellWbPart = _doc.WorkbookPart\n                ?? throw new InvalidOperationException(\"Workbook not found\");","sourceCodeStart":896,"sourceCodeEnd":932,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs#L896-L932","documentation":"Before the style filter runs, AddCell checks each property key against CellPropHints — keys that are genuinely ambiguous in cell context (e.g. `color`, which could be font.color or fill; `path`, which is not a cell property). If any ambiguous key is present, it throws listing all hints rather than silently dropping the key. Without this, Add would silently drop the key while Set loudly rejects it — inconsistent, and the caller's intent would be lost.","triggerScenarios":"Add(\"/Sheet1/A1\",\"cell\",pos,{[\"color\"]=\"FF0000\", ...}); props contains 'path=...'; any prop key present in CellPropHints.AmbiguousKeys (currently 'color' and 'path').","commonSituations":"Carrying flat keys over from PPT/Word run properties where 'color' means text color; using 'path' (a picture/ole key) on a cell; copy-pasting a prop bag from another element type.","solutions":["For text color use font.color; for background color use fill (or its aliases).","For the cell address use 'ref' (or 'address'), not 'path'.","Remove the ambiguous key and replace it with the specific namespaced key the error hint suggests."],"exampleFix":"// before\nhandler.Add(\"/Sheet1/A1\", \"cell\", null, new() { [\"color\"] = \"FF0000\", [\"value\"] = \"x\" });\n// after\nhandler.Add(\"/Sheet1/A1\", \"cell\", null, new() { [\"font.color\"] = \"FF0000\", [\"value\"] = \"x\" });","handlingStrategy":"validation","validationCode":"static readonly HashSet<string> Ambiguous = new(StringComparer.OrdinalIgnoreCase){\"color\",\"path\"};\nforeach (var k in props.Keys)\n    if (Ambiguous.Contains(k))\n        throw new ArgumentException($\"'{k}' is ambiguous in cell context; use font.color/fill or ref/address\");","typeGuard":"static bool IsUnambiguousCellKey(string k) =>\n    !k.Equals(\"color\", StringComparison.OrdinalIgnoreCase)\n    && !k.Equals(\"path\", StringComparison.OrdinalIgnoreCase);","tryCatchPattern":"try { h.Add(parentPath, \"cell\", pos, props); }\ncatch (ArgumentException ex) when (ex.Message.StartsWith(\"Unsupported cell property\"))\n{ /* replace 'color' with font.color/fill, 'path' with ref/address, and retry */ }","preventionTips":["Use namespaced keys (font.color, fill, border.*) for cell styling.","Use ref/address for the cell target, never path.","Do not reuse flat PPT/Word run keys on Excel cells."],"tags":["excel","xlsx","cell","style","ambiguous-property","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}