iOfficeAI/OfficeCLI · error · System.ArgumentException
Sheet not found: {cfSheetName}
Error message
Sheet not found: {cfSheetName} What it means
Thrown by AddDataBar when FindWorksheet(cfSheetName) returns null. The sheet name is the first segment of parentPath after trimming the leading slash. This fires after the type-allowlist check (498) passes, so the type was valid (or defaulted to databar) but the sheet segment does not resolve to a worksheet.
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Cf.cs:126
return Add(parentPath, "cfextended", position, properties);
// R10: Reject unknown CF types instead of silently falling through to
// dataBar. The `cf` alias (AddCf) already throws on unknowns; mirror
// the behavior here so both `--type cf` and `--type conditionalformatting`
// share the same allowlist (CONSISTENCY(cf-type-allowlist)). `databar`
// is the documented default for this alias, so allow it explicitly.
if (cfTypeLower is not "databar")
{
throw new ArgumentException(
$"Unknown CF type '{cfTypeProp}'. Valid: databar, iconset, colorscale, formula, cellIs, "
+ "top10, topPercent, bottom, bottomPercent, aboveAverage, belowAverage, "
+ "uniqueValues, duplicateValues, containsText, notContains, beginsWith, endsWith, "
+ "containsBlanks, notContainsBlanks, containsErrors, notContainsErrors, dateOccurring.");
}
}
var cfSegments = parentPath.TrimStart('/').Split('/', 2);
var cfSheetName = cfSegments[0];
var cfWorksheet = FindWorksheet(cfSheetName)
?? throw new ArgumentException($"Sheet not found: {cfSheetName}");
// R22-2: a path-tail range (/Sheet1/A1:A3) is the sqref fallback before
// the hardcoded "A1:A10" — previously csSegments[1] was silently ignored.
var cfPathRange = cfSegments.Length > 1 && !string.IsNullOrEmpty(cfSegments[1]) ? cfSegments[1] : "A1:A10";
var sqref = ValidateSqref(properties.GetValueOrDefault("sqref") ?? properties.GetValueOrDefault("range") ?? properties.GetValueOrDefault("ref", cfPathRange), "ref");
var minVal = properties.ContainsKey("min") ? properties["min"] : (string?)null;
var maxVal = properties.ContainsKey("max") ? properties["max"] : (string?)null;
// The schema documents min/max as "numeric or 'auto'". 'auto' is the
// automatic-bound sentinel, NOT a literal value: emitting it as a
// numeric cfvo (<cfvo type="num" val="auto"/>) is malformed and Excel
// silently drops the whole data bar. Map it back to null so the cfvo
// builders below pick the type="min"/type="max" (and x14 AutoMin/AutoMax)
// branches — identical to the user omitting the bound entirely.
if (string.Equals(minVal, "auto", StringComparison.OrdinalIgnoreCase)) minVal = null;
if (string.Equals(maxVal, "auto", StringComparison.OrdinalIgnoreCase)) maxVal = null;
var cfColor = properties.GetValueOrDefault("color", "638EC6");
var normalizedColor = ParseHelpers.NormalizeArgbColor(cfColor);
View on GitHub (pinned to 1ced45e900)
Solutions
- Confirm the sheet exists via a Get on / and use the exact name.
- Create the sheet first if it is missing.
- Ensure the path begins with /<exactSheetName> (a trailing /A1:A10 range is optional but allowed).
Example fix
// before
handler.Add("/SheetZ", "cf", null, props); // SheetZ missing
// after
handler.Add("/Sheet1", "cf", null, props); Defensive patterns
Strategy: validation
Validate before calling
string sheet = parentPath.TrimStart('/').Split('/', 2)[0];
var sheets = handler.Query("/");
if (!sheets.Any(s => string.Equals(s.Name, sheet, StringComparison.OrdinalIgnoreCase)))
throw new InvalidOperationException($"Sheet not found: {sheet}");
handler.Add(parentPath, "cf", null, props); Type guard
static bool SheetExists(IExcelHandler h, string sheet)
=> h.Query("/").Any(s => string.Equals(s.Name, sheet, StringComparison.OrdinalIgnoreCase)); Try / catch
try { handler.Add(parentPath, "cf", null, props); }
catch (ArgumentException ex) when (ex.Message.StartsWith("Sheet not found"))
{ /* create the sheet or report the missing name */ } Prevention
- Resolve the sheet segment from a current sheet listing before Add.
- Create the sheet first if it does not exist.
- Note the path-tail range (/Sheet1/A1:A10) is optional but the sheet segment is mandatory.
When it happens
Trigger: Add type=cf or type=conditionalformatting with parentPath="/BadSheet" or a path whose sheet segment is not a worksheet. A path-tail range (e.g. /Sheet1/A1:A3) is fine because only the first segment is used for the sheet lookup; the range is consumed later as the sqref fallback.
Common situations: Sheet renamed or deleted after the path was captured. Script reuses a sheet name from a different workbook. Typo or trailing whitespace in the sheet segment.
Related errors
- Unknown CF type '{cfTypeRaw}'. Valid: databar, iconset, colo
- Sheet not found: {runSheetName}
- Sheet not found: {rbSheetName}
- Sheet not found: {cbSheetName}
- Unknown CF type '{cfTypeProp}'. Valid: databar, iconset, col
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/88e131aabbb646cb.
Report an issue: GitHub.