iOfficeAI/OfficeCLI · error · ArgumentException

raw-set: XPath matched no elements: {xpath}. Hint: auto-regi

Error message

raw-set: XPath matched no elements: {xpath}. Hint: auto-registered namespace prefixes: {string.Join(", ", CommonNamespaces.Keys.Order())}. No xmlns declarations needed in --xml fragments.

What it means

Thrown when the XPath expression matched zero elements in the target XML. This is a deliberate design choice: RawXmlHelper throws rather than silently returning 0 affected nodes, because a stderr nudge would be trivially dropped by pipelines and batch envelopes, making a typo'd XPath look identical to a successful no-op mutation. The error message lists all auto-registered namespace prefixes so the caller can fix the XPath without guessing.

Source

Thrown at src/officecli/Core/RawXmlHelper.cs:153

            case "replace":
            case "remove":
            case "delete":
            case "setattr":
                break;
            default:
                throw new ArgumentException($"Unknown action: {action}. Supported: append, prepend, insertbefore, insertafter, replace, remove, setattr");
        }

        var nodes = xDoc.XPathSelectElements(xpath, nsManager).ToList();
        if (nodes.Count == 0)
        {
            // Throw rather than return 0 affected with a stderr nudge: the
            // stderr line is trivially dropped by pipelines and batch
            // envelopes, leaving callers with success:true on a no-op. A
            // typo'd xpath then looks indistinguishable from a real
            // mutation. Surface the failure where every consumer
            // (standalone, batch, resident) already handles exceptions.
            throw new ArgumentException(
                $"raw-set: XPath matched no elements: {xpath}. " +
                "Hint: auto-registered namespace prefixes: " +
                string.Join(", ", CommonNamespaces.Keys.Order()) +
                ". No xmlns declarations needed in --xml fragments.");
        }

        int affected = 0;

        foreach (var node in nodes)
        {
            switch (action.ToLowerInvariant())
            {
                case "append":
                    if (xml == null) throw new ArgumentException("--xml is required for append");
                    var appendFragment = ParseFragment(xml, xDoc);
                    foreach (var el in appendFragment)
                        node.Add(el);
                    affected++;

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Check the error's hint: it lists all auto-registered namespace prefixes (e.g. w, r, p, mc, a). Use one of those prefixes in your XPath.
  2. Test the XPath against the actual XML: dump the part with `raw-read --part <uri>` and evaluate the XPath against it.
  3. Verify the element name spelling — OOXML names are terse and easily confused (w:pPr vs w:pStyle vs w:p).
  4. If the element should exist but doesn't, the document structure may differ from your assumption — inspect it first with raw-read.
  5. Use namespace-agnostic XPath if the prefix isn't registered: //*[local-name()='pPr'] instead of //w:pPr.

Example fix

// before: wrong namespace prefix not in CommonNamespaces
RawXmlHelper.Execute(root, "//mycustom:elem", "append", "<w:p/>");

// after: use auto-registered prefix, or local-name fallback
RawXmlHelper.Execute(root, "//w:pPr", "append", "<w:p/>");
// or namespace-agnostic:
RawXmlHelper.Execute(root, "//*[local-name()='pPr']", "append", "<w:p/>");
Defensive patterns

Strategy: validation

Validate before calling

// Test the XPath against the XML before mutating
var testDoc = XDocument.Parse(rootElement.OuterXml);
var nsManager = BuildNamespaceManager(testDoc);  // or use CommonNamespaces
var matchCount = testDoc.XPathEvaluate(xpath, nsManager) switch
{
    IEnumerable<XElement> els => els.Count(),
    _ => 0
};
if (matchCount == 0)
    Console.Error.WriteLine($"Warning: XPath '{xpath}' matched 0 elements. Check prefix/element name.");

Try / catch

try
{
    var affected = RawXmlHelper.Execute(rootElement, xpath, action, xml);
}
catch (ArgumentException ex) when (ex.Message.Contains("XPath matched no elements"))
{
    // The XPath didn't match. The error lists auto-registered namespace prefixes.
    // Use one of those prefixes, or try local-name() XPath.
    Console.Error.WriteLine(ex.Message);
    // Fallback: namespace-agnostic XPath
    var localName = ExtractLocalName(xpath);
    RawXmlHelper.Execute(rootElement, $"//*[local-name()='{localName}']", action, xml);
}

Prevention

When it happens

Trigger: RawXmlHelper.ExecuteOnXmlString evaluates XPathSelectElements(xpath, nsManager).ToList() and the result count is 0. The XPath didn't match any element in the part's XML — due to a typo, wrong namespace prefix, wrong element name, or a document structure that differs from expectation.

Common situations: Namespace prefix in the XPath isn't auto-registered (the hint lists CommonNamespaces.Keys). XPath targets an element that exists in a different part (e.g. querying footnotes.xml XPath against document.xml). Element name typo: //w:pP instead of //w:pPr. Structural mismatch: the document doesn't have the expected nesting. XPath uses a prefix the document doesn't declare.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/521c59dcd5c698ea. Report an issue: GitHub.