OrchardCMS/OrchardCore · error · InvalidOperationException

Unknown XmlRpc value type

Error message

Unknown XmlRpc value type {element.Name.LocalName}

What it means

ResumeWorkflowAsync continues an existing, halted workflow instance by locating the activity identified by activityId among the workflow's blocking activities. When the given activityId is not in the instance's BlockingActivityIds it throws InvalidOperationException, since only a blocked (awaiting) activity can be resumed — resuming elsewhere would corrupt the workflow state machine.

Solutions

  1. Verify the activityId is in workflow.BlockingActivityIds (or query the blocking activities) before calling ResumeWorkflowAsync and resume only the actual halted activity.
  2. Use the workflow's current blocking activity id(s) — e.g. fetch the instance by correlation id and read its blocking activities — rather than a hardcoded id.
  3. If the activity already ran, do not resume; either treat the workflow as complete or restart it via RestartWorkflowAsync.
  4. Fix out-of-band edits to workflow instances that cleared or altered BlockingActivityIds by restoring the instance from a backup or re-running the flow.

Example fix

// before
await workflowManager.ResumeWorkflowAsync(workflow, "activity-1", "Signal", input); // may throw
// after
if (workflow.BlockingActivityIds.Contains("activity-1"))
{
    await workflowManager.ResumeWorkflowAsync(workflow, "activity-1", "Signal", input);
}
Defensive patterns

Strategy: validation

Validate before calling

// before resume
if (workflow?.BlockingActivityIds?.Contains(activityId) != true)
    throw new InvalidOperationException($"Activity '{activityId}' is not a blocking activity of workflow '{workflow?.Id}'.");

Type guard

static bool IsResumable(Workflow workflow, string activityId) =>
    workflow?.BlockingActivityIds?.Contains(activityId) == true;

Try / catch

try { await workflowManager.ResumeWorkflowAsync(workflow, activityId, eventName, input); }
catch (InvalidOperationException ex) when (ex.Message.Contains("is not a blocking activity"))
{ logger.LogWarning(ex, "Attempted resume on non-blocking activity {ActivityId}", activityId); /* re-read instance and resume correct activity */ }

Prevention

When it happens

Trigger: Calling ResumeWorkflowAsync with an activityId that is not currently blocking: the activity already completed, the workflow halted at a different activity, a stale/wrong activityId was passed, or the workflow instance data was modified out-of-band so BlockingActivityIds no longer contains that id.

Common situations: Signal/callback handlers resuming with a hardcoded or cached activityId after the workflow definition changed; double-resume where the first signal already advanced past the activity; copied correlation logic resuming the wrong workflow instance; imported workflow instances with rebuilt blocking lists.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/f21dbb2a7f88f041. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore.Modules/OrchardCore.XmlRpc/Services/XmlRpcReader.cs:81

    /// <summary>
    /// Maps an XML element to rpc data.
    /// </summary>
    /// <param name="source">The XML element to be mapped.</param>
    /// <returns>The rpc data.</returns>
    public XRpcData MapToData(XElement source)
    {
        var value = source.Element("value");
        if (value == null)
        {
            return new XRpcData();
        }

        var element = value.Elements().SingleOrDefault();

        Func<XElement, XRpcData> dispatch;
        if (_dispatch.TryGetValue(element.Name.LocalName, out dispatch) == false)
        {
            throw new InvalidOperationException("Unknown XmlRpc value type " + element.Name.LocalName);
        }

        return dispatch(element);
    }

    /// <summary>
    /// Maps an XML element to a rpc struct.
    /// </summary>
    /// <param name="source">The XML element to be mapped.</param>
    /// <returns>The rpc struct.</returns>
    public XRpcStruct MapToStruct(XElement source)
    {
        var result = new XRpcStruct();
        foreach (var member in source.Elements("member"))
        {
            result.Members.Add(
                (string)member.Element("name"),
                MapValue(member.Element("value")));

View on GitHub (pinned to 4306c0717f)