flowable/flowable-engine · error · FlowableException

Could not evaluate xpath expression

Error message

Could not evaluate xpath expression ${xpathExpression}

What it means

XpathBasedInboundEventTenantDetector.detectTenantId compiles its configured xpathExpression and evaluates it against the XML payload Document, expecting a Node whose text content is the tenant id. Any failure — invalid XPath syntax, non-node result, null result leading to NPE, or evaluation error — is wrapped in FlowableException 'Could not evaluate xpath expression <expr>'.

Solutions

  1. Verify the xpathExpression syntax with an XPath tester or an xPath.compile() call outside the flow.
  2. Check the payload actually contains an element matching the expression (missing matches yield null -> NPE inside the try).
  3. Account for XML namespaces — use namespace-aware XPath or local-name() predicates if the document uses namespaces.
  4. Confirm this detector is only applied to XML payloads, not JSON.
  5. After fixing, the detector returns result.getTextContent(); ensure the matched node's text is the tenant id.

Example fix

// before
xpathExpression = "/order/tenanttId"; // typo -> no match -> NPE

// after
xpathExpression = "/order/tenantId";
Defensive patterns

Strategy: validation

Validate before calling

try {
    XPathFactory.newInstance().newXPath().compile(xpathExpression);
} catch (XPathExpressionException e) {
    throw new IllegalArgumentException("Invalid tenant-detector xpath: " + xpathExpression, e);
}
// xpath syntax is valid; also confirm a node matches in test payloads

Try / catch

try {
    String tenantId = detector.detectTenantId(document);
} catch (FlowableException e) {
    logger.error("Tenant detection failed for xpath: {}", detector.getXpathExpression(), e.getCause());
    throw e;
}

Prevention

When it happens

Trigger: detectTenantId(payload) called (directly or via tenantId/test code) when the configured xpathExpression is syntactically invalid, matches no node (evaluate returns null and result.getTextContent() NPEs), or matches a non-Node result type; also when the payload Document is incompatible with the expression.

Common situations: Typo'd XPath in tenant-detector configuration; XPath written for a document where the tenant element is absent (testDetectTenantIdMissingTenantIdInXml); namespace-qualified XML where the plain XPath matches nothing; wrong detector configured for JSON payloads.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/9c6bbbb78eb198d9. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/tenantdetector/XpathBasedInboundEventTenantDetector.java:42

/**
 * @author Joram Barrez
 */
public class XpathBasedInboundEventTenantDetector implements InboundEventTenantDetector<Document> {

    protected String xpathExpression;

    public XpathBasedInboundEventTenantDetector(String xpathExpression) {
        this.xpathExpression = xpathExpression;
    }

    @Override
    public String detectTenantId(Document payload) {
        try {
            XPath xPath = XPathFactory.newInstance().newXPath();
            Node result = (Node) xPath.compile(xpathExpression).evaluate(payload, XPathConstants.NODE);
            return result.getTextContent();
        } catch (Exception e) {
            throw new FlowableException("Could not evaluate xpath expression " + xpathExpression, e);
        }
    }

    public String getXpathExpression() {
        return xpathExpression;
    }
    public void setXpathExpression(String xpathExpression) {
        this.xpathExpression = xpathExpression;
    }
}

View on GitHub (pinned to d6d39ce1c6)