How to update task property of type NodeRef using REST API?

Showing results for 
Search instead for 
Did you mean: 
Active Member

How to update task property of type NodeRef using REST API?

Note: This is a clone of my original post located in the wrong forum: How to update task property of type NodeRef using REST API? 



I'm working on a project which integrates with Alfresco v4.2.e and Activiti v5.13.

I use the REST API to query for tasks through the task-instance service.

When a property is a (collection of) NodeRef, It returns a (collection of) string ("workspace://....").
When I try to update this property, Alfresco throws a ClassCastException saying that String cannot be cast to NodeRef.

I found this bug on your jira   which seems to be related to my problem but in the other direction. Is my problem a bug? Is this a bug fixed in the v4.2.f? Did I do something wrong?


Anyway I decided to try the activiti-rest webapp to query directly Activiti. So I searched the war for the 5.13.

Unfortunately the Activiti website doesn't provide a long history of binaries. I had to build the war using the sources from github. When I deployed the compiled war to a Tomcat and tried to get variables through the runtime/tasks service, It throws a ActivitiException "unknown variable type name alfrescoScriptNodeList". Indeed in some Maven repo I've seen some Activiti jars suffixed by "alf". Did I built the wrong war? Is there a fork of the project?


Finally I could write a webscript in Alfresco using the Alfresco Java API but it would be the last option...


Sorry for the length of this text and thanks in advance for your answers.

4 Replies
Active Member

Re: How to update task property of type NodeRef using REST API?

No one has an answer? I can't imagine I'm the only one who would like to update a nodeRef inside a task using REST...


Re: How to update task property of type NodeRef using REST API?

It isn't really clear what you are trying to do. 

  • What is your goal? I'm not clear on which REST API you are trying to access, Activiti or Alfresco Community Edition.
  • What did you try? A small section of code is often helpful here.
  • What happened? What is the exact error, and where was it thrown?

That might help people assist you.

Active Member

Re: How to update task property of type NodeRef using REST API?

You're right I missed some crucial information. My apologies

I use the Workflow repository from the Alfresco Community Edition 4.2.e Rest API, documented here: Workflow | Alfresco Documentation

To get a specific workflow instance, I use the endpoint documented here: Get workflow instance | Alfresco Documentation. Some task instances of a workflow instance have a property of type NodeRef.

In the JSON response, a NodeRef property is represented as follow:


Now I want to update some properties of a task instance. For that I use the endpoint documented here: Updates workflow task instance | Alfresco Documentation.

The task instance is well updated except if I include a property of type NodeRef.

In that case I receive a status code 500 from the Alfresco REST API. When I check the logs of Alfresco, I see this stacktrace:

Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to org.alfresco.service.cmr.repository.NodeRef
        at org.alfresco.repo.workflow.activiti.ActivitiNodeConverter.convertNodes(
        at org.alfresco.repo.workflow.AbstractWorkflowNodeConverter.convertNodes(
        at org.alfresco.repo.workflow.AbstractWorkflowNodeConverter.convertNodes(
        at org.alfresco.repo.workflow.AbstractWorkflowPropertyHandler.convertAssociationValue(
        at org.alfresco.repo.workflow.AbstractWorkflowPropertyHandler.handleAssociation(
        at org.alfresco.repo.workflow.AbstractWorkflowPropertyHandler.handleDefaultProperty(
        at org.alfresco.repo.workflow.DefaultWorkflowPropertyHandler.handleProperty(
        at org.alfresco.repo.workflow.WorkflowPropertyHandlerRegistry.handleVariablesToSet(
        at org.alfresco.repo.workflow.activiti.ActivitiWorkflowEngine.updateTask(
        at org.alfresco.repo.workflow.WorkflowServiceImpl.updateTask(

In the PUT HTTP method, I set the property of type NodeRef as follow:


I talked about the Activiti REST API as a workaround: I installed it and configured with the same database as the Activiti bundled with Alfresco to see if I could update task instances by this way. But it's not a good idea.

I hope I have been clearer and thanks for your help.

Active Member

Re: How to update task property of type NodeRef using REST API?

As a workaround I ended up writing a Webscript which do the same as the Alfresco one but with NodeRef handling.
I'ts a bit dirty as I had to parse the string to see if it starts with "workspace://.."

Anyway I'm always interested if someone has the solution or a better workaround.

Here's the code :

public class UpdateTaskProperties extends AbstractWebScript {

    private static final String TASK_ID_PARAM = "taskId";
    private static Logger LOGGER = LoggerFactory.getLogger(UpdateTaskProperties.class);

    private final ObjectMapper objectMapper = new ObjectMapper();
    private final NodeRefObjectMapper nodeRefObjectMapper = new NodeRefObjectMapper();

    public UpdateTaskProperties() {

    public void execute(WebScriptRequest request, WebScriptResponse response) throws IOException {
        String taskId = getTaskIdIn(request);

        Map<String, Object> properties = objectMapper.readValue(request.getContent().getReader(), Map.class);

        Map<String, Object> finalProperties = collectCastedPropertiesFrom(properties);

        LOGGER.debug("Updating " + finalProperties.size() + " properties of task " + taskId + "...");

        taskService.setVariablesLocal(taskId, finalProperties);"Updated " + finalProperties.size() + " properties of task " + taskId);

    private String getTaskIdIn(WebScriptRequest request) {
        String taskId = request.getParameter(TASK_ID_PARAM);
        isTrue(isNotBlank(taskId), "Invalid task id");
        return taskId;

    private Map<String, Object> collectCastedPropertiesFrom(Map<String, Object> properties) {
        Map<String, Object> finalProperties = newHashMap();
        for (String propertyName : properties.keySet()) {
            Object value = properties.get(propertyName);
            if (nodeRefObjectMapper.isNodeRef(value)) {
                finalProperties.put(propertyName, nodeRefObjectMapper.readValue(value));
            } else if (nodeRefObjectMapper.isNodeRefCollection(value)) {
                finalProperties.put(propertyName, nodeRefObjectMapper.readValues(value));
            } else {
                finalProperties.put(propertyName, value);
        return finalProperties;

public class NodeRefObjectMapper {

    private static final String WORKSPACE_PREFIX = "workspace://SpacesStore/";
    private static final String NOTHING = "";

    public NodeRef readValue(Object value) {
        isTrue(isNodeRef(value), "Not a NodeRef object");
        return toNodeRef((String) value);

    public Collection<NodeRef> readValues(Object value) {
        isTrue(isNodeRefCollection(value), "Not a NodeRef collection object");
        return from((Collection<String>) value)
                .transform(s -> toNodeRef(s)).toList();

    public boolean isNodeRef(Object value) {
        return value instanceof String && normalize((String) value).startsWith(WORKSPACE_PREFIX);

    public boolean isNodeRefCollection(Object value) {
        return value instanceof Collection
                && !((Collection) value).isEmpty()
                && isNodeRef(((Collection) value).iterator().next());

    private NodeRef toNodeRef(String value) {
        return new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, toNodeRefId(value));

    private String toNodeRefId(String nodeRef) {
        return normalize(nodeRef).replace(WORKSPACE_PREFIX, NOTHING);

    private String normalize(String value) {
        return value.replace("\\", "");