iOfficeAI/OfficeCLI · warning · ArgumentException
docProps is a singleton; use /docProps or / (no index).
Error message
docProps is a singleton; use /docProps or / (no index).
What it means
Thrown by ExcelHandler.Get when the first path segment is /docProps[N]. docProps (core/extended document properties) is a document-level singleton part with exactly one instance per workbook, so an index is meaningless. The guard redirects the caller to the canonical /docProps (or /) route instead of treating 'docProps[N]' as a sheet name, which would otherwise raise a misleading SheetNotFoundException. Mirrors the /workbook[N] singleton redirect.
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Query.cs:230
nrNode.Format["comment"] = dn.Comment.Value;
if (dn.Function?.Value == true)
nrNode.Format["volatile"] = true;
return nrNode;
}
// Parse path: /SheetName or /SheetName/A1 or /SheetName/A1:D10
var segments = path.TrimStart('/').Split('/', 2);
var sheetNameFromPath = segments[0];
// workbook is a singleton at the document root — reject an indexed
// /workbook[N] with a redirect rather than treating "workbook[N]" as a
// sheet name (which fires a misleading SheetNotFoundException). Mirrors
// the pptx notes[N]/theme[N] and docx watermark[N] redirects.
if (Regex.IsMatch(sheetNameFromPath, @"^workbook\[\d+\]$", RegexOptions.IgnoreCase))
throw new ArgumentException("workbook is a singleton; use /workbook or / (no index).");
// docProps is a document-level part, not a sheet — same redirect class.
if (Regex.IsMatch(sheetNameFromPath, @"^docProps\[\d+\]$", RegexOptions.IgnoreCase))
throw new ArgumentException("docProps is a singleton; use /docProps or / (no index).");
var worksheet = FindWorksheet(sheetNameFromPath);
if (worksheet == null)
throw SheetNotFoundException(sheetNameFromPath);
// CONSISTENCY(path-stability): if the path used sheet[N] / sheet[last()],
// rebuild the canonical path with the resolved sheet name so the returned
// node.Path reflects the actual sheet (matches Word's last() echo behavior).
var resolvedSheetName = ResolveSheetName(sheetNameFromPath);
if (!resolvedSheetName.Equals(sheetNameFromPath, StringComparison.Ordinal))
{
sheetNameFromPath = resolvedSheetName;
path = segments.Length == 1 ? $"/{resolvedSheetName}" : $"/{resolvedSheetName}/{segments[1]}";
}
var data = GetSheet(worksheet).GetFirstChild<SheetData>();
if (data == null)
return new DocumentNode { Path = path, Type = "sheet", Preview = "(empty)" };
if (segments.Length == 1)View on GitHub (pinned to 1ced45e900)
Solutions
- Drop the index: call handler.Get("/docProps") (or Get("/") for the whole workbook).
- Special-case singleton root parts (docProps, workbook) in any generic path builder so they emit no index.
- Pre-validate the path: regex ^docProps\[\d+\]$ => rewrite to /docProps before calling Get.
Example fix
// before
var props = handler.Get("/docProps[1]"); // throws
// after
var props = handler.Get("/docProps"); Defensive patterns
Strategy: validation
Validate before calling
// docProps/workbook are singletons — strip any [N] before Get
var head = path.TrimStart('/').Split('/', 2)[0];
if (Regex.IsMatch(head, @"^(?:workbook|docProps)\[\d+$", RegexOptions.IgnoreCase))
path = "/" + head.Split('[')[0];
return handler.Get(path); Type guard
static bool IsIndexedSingleton(string path) =>
Regex.IsMatch(path.TrimStart('/').Split('/', 2)[0],
@"^(?:workbook|docProps)\[\d+\]$", RegexOptions.IgnoreCase); Prevention
- Never append an index to root-level singleton parts (docProps, workbook).
- When generating paths generically from the '/' tree, special-case singletons to emit no index.
- Pre-validate the path shape before calling Get.
When it happens
Trigger: Calling handler.Get("/docProps[1]"), Get("/docProps[2]"), or any /docProps[N] on an opened .xlsx. Happens when a generic path builder appends [1] to every top-level node it discovers under /.
Common situations: Code that synthesizes element paths as name[index] for all root nodes. Copy-pasting a /sheet[1] or /chart[1] pattern onto document-level parts. Misreading the tree where docProps sits at the document root, not under a sheet.
Related errors
- Pivot name '{explicitName}' already exists in workbook
- workbook is a singleton; use /workbook or / (no index).
- Row break index {rbIdx} out of range (1-{breaks.Count})
- Column break index {cbIdx} out of range (1-{breaks.Count})
- No charts found in sheet
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/6d61d264aee091b6.
Report an issue: GitHub.