{"record":{"id":"37266f1654b7db1f","repo":"iOfficeAI/OfficeCLI","slug":"cannot-store-datetext-as-date-value-must-be-i","errorCode":null,"errorMessage":"Cannot store '{dateText}' as date; value must be ISO 8601 (yyyy-MM-dd) and represent a real calendar day. Use type=string to keep the literal text.","messagePattern":"Cannot store '(.+?)' as date; value must be ISO 8601 \\(yyyy-MM-dd\\) and represent a real calendar day\\. Use type=string to keep the literal text\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs","lineNumber":753,"sourceCode":"                    if (!string.IsNullOrEmpty(dateText)\n                        && TryParseIsoDateFlexible(dateText, out var dt))\n                    {\n                        // Mirrors Set's pre-1900 guard: Excel's serial epoch is\n                        // 1899-12-30; earlier dates round-trip as the epoch and\n                        // mislead the user. Reject instead of silently clamping.\n                        if (dt < new System.DateTime(1900, 1, 1))\n                            throw new ArgumentException(\n                                $\"Cannot store '{dateText}' as date; Excel does not support dates before 1900-01-01 \" +\n                                $\"(serial epoch is 1899-12-30). Use type=string to keep the literal text.\");\n                        cell.CellValue = new CellValue(\n                            ExcelDataFormatter.ToExcelSerial(dt, IsWorkbookDate1904()).ToString(System.Globalization.CultureInfo.InvariantCulture));\n                    }\n                    else if (!string.IsNullOrEmpty(dateText))\n                    {\n                        // BUG-FIX(B10): if user said type=date but the value isn't\n                        // parseable, refuse to leave a date-shaped string in a\n                        // numeric-styled cell — that produces invalid OOXML.\n                        throw new ArgumentException(\n                            $\"Cannot store '{dateText}' as date; value must be ISO 8601 (yyyy-MM-dd) \" +\n                            $\"and represent a real calendar day. Use type=string to keep the literal text.\");\n                    }\n                    // Apply a default date number format unless the caller\n                    // already supplied one — matches Set's type=date guard.\n                    if (!properties.ContainsKey(\"numberformat\")\n                        && !properties.ContainsKey(\"numfmt\")\n                        && !properties.ContainsKey(\"format\"))\n                    {\n                        properties[\"numberformat\"] = \"yyyy-mm-dd\";\n                    }\n                }\n            }\n        }\n        if (properties.TryGetValue(\"clear\", out _))\n        {\n            cell.CellValue = null;\n            cell.CellFormula = null;","sourceCodeStart":735,"sourceCodeEnd":771,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs#L735-L771","documentation":"When type=date is supplied but the value is non-empty and cannot be parsed as an ISO 8601 date (yyyy-MM-dd, with optional T-separated time), this throws rather than leaving a date-shaped string in a numeric-styled cell — which would produce invalid OOXML. It mirrors Set's type=date guard so a non-parseable date value is rejected up front.","triggerScenarios":"Add(\"/Sheet1/A1\",\"cell\",pos,{[\"type\"]=\"date\",[\"value\"]=\"13/01/2020\"}); value=\"Jan 1 2020\" (not ISO); value=\"2020/01/01\" (slashes, not ISO dashes); value=\"2020-13-01\" (invalid month).","commonSituations":"Locale-specific date formats (DD/MM/YYYY, month-name forms); values from a system that emits non-ISO dates; a timezone-offset suffix that TryParseIsoDateFlexible does not accept.","solutions":["Pass the date in ISO 8601 form: yyyy-MM-dd (e.g. 2020-01-13) or yyyy-MM-ddTHH:mm:ss.","If the source date is in another format, parse and re-format to ISO before the call.","If the value is not a date, use type=string."],"exampleFix":"// before\nhandler.Add(\"/Sheet1/A1\", \"cell\", null, new() { [\"type\"] = \"date\", [\"value\"] = \"13/01/2020\" });\n// after\nvar iso = DateTime.Parse(\"13/01/2020\", CultureInfo.InvariantCulture).ToString(\"yyyy-MM-dd\");\nhandler.Add(\"/Sheet1/A1\", \"cell\", null, new() { [\"type\"] = \"date\", [\"value\"] = iso });","handlingStrategy":"validation","validationCode":"if (props.GetValueOrDefault(\"type\")?.Equals(\"date\", StringComparison.OrdinalIgnoreCase) == true\n    && props.TryGetValue(\"value\", out var dv) && !string.IsNullOrEmpty(dv))\n{\n    if (!DateTime.TryParseExact(dv, new[]{\"yyyy-MM-dd\",\"yyyy-MM-ddTHH:mm:ss\"}, CultureInfo.InvariantCulture, DateTimeStyles.None, out _))\n        throw new ArgumentException(\"date value is not ISO 8601\");\n}","typeGuard":"static bool IsIsoDate(string? s) =>\n    !string.IsNullOrEmpty(s) && DateTime.TryParseExact(s, new[]{\"yyyy-MM-dd\",\"yyyy-MM-ddTHH:mm:ss\"},\n        CultureInfo.InvariantCulture, DateTimeStyles.None, out _);","tryCatchPattern":"try { h.Add(parentPath, \"cell\", pos, props); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"must be ISO 8601\"))\n{ /* re-format the source date to yyyy-MM-dd and retry, or use string */ }","preventionTips":["Convert all dates to ISO 8601 (yyyy-MM-dd) before setting type=date.","Do not pass locale date formats (DD/MM/YYYY) to date-typed cells.","Use type=string for non-date text."],"tags":["excel","xlsx","cell","date","iso8601","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}