dotCMS / dotCMS/core

Workflow fire endpoint returns misleading ClassCastException for array-valued checkbox fields

Open
#34,815 5 comments 0 reactions 1 assignee View on GitHub

@fmontes is already working on this.

Since Mar 2, 2026.

dotCMS : Rest API OKR : Customer Support Team : Maintenance
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Problem Statement

The workflow fire endpoint PUT /api/v1/workflow/actions/default/fire/PUBLISH returns a misleading ClassCastException when checkbox or multi-select fields are sent as JSON arrays instead of comma-separated strings. The error message gives no indication of the actual problem -- it looks like an internal server error rather than a client input validation issue.

Error returned:

{"message":"class java.util.LinkedHashMap cannot be cast to class com.dotmarketing.portlets.contentlet.model.Contentlet"}

This is confusing for API consumers because:

  1. The error mentions LinkedHashMap and Contentlet -- internal implementation details unrelated to the user's mistake
  2. There is no mention of which field is problematic or what format is expected
  3. It returns as a 500-level error when it should be a 400 Bad Request with a clear validation message

Steps to Reproduce

  1. Send a PUT request to /api/v1/workflow/actions/default/fire/PUBLISH with checkbox fields as JSON arrays:
{
  "contentlet": {
    "contentType": "Blog",
    "identifier": "0edfee78-2a75-4f3d-bf20-813aae15d4e9",
    "languageId": "1",
    "title": "Test Blog Post",
    "searchEngineIndex": ["index", "follow", "snippet"],
    "sitemap": ["true"]
  }
}
  1. Observe the error response:
{"message":"class java.util.LinkedHashMap cannot be cast to class com.dotmarketing.portlets.contentlet.model.Contentlet"}
  1. The workaround is to send checkbox values as comma-separated strings instead:
{
  "contentlet": {
    "searchEngineIndex": "index,follow,snippet",
    "sitemap": "true"
  }
}

Acceptance Criteria

  • When checkbox/multi-select fields are sent as JSON arrays, the API should either:
    • (Option A - Preferred) Automatically convert JSON arrays to comma-separated strings internally (e.g., ["index", "follow"] -> "index,follow")
    • (Option B) Return a clear 400 Bad Request with a message like: "Field 'searchEngineIndex' is a checkbox field and expects a comma-separated string (e.g., 'index,follow,snippet'), but received an array"
  • The ClassCastException should never bubble up to the API consumer -- it should be caught and translated to a meaningful error
  • Add type-safety checks in groupContentletsByLanguage() to prevent ClassCastException even if unexpected types reach that code path

Root Cause Analysis

The issue flows through these components:

  1. MapToContentletPopulator.processMap() (line ~129-162): Receives the raw field map and passes it to getContentletRelationships() before field type validation occurs
  2. MapToContentletPopulator.getContentletRelationships() (line ~692-803): Iterates over all relationships for the content type and checks the raw map for matching keys. When non-string values (arrays from checkbox fields) are present in the map, they can interfere with relationship processing
  3. ESContentletAPIImpl.groupContentletsByLanguage() (line ~8832-8841): Performs Collectors.toMap(Contentlet::getIdentifier, ...) which throws ClassCastException when non-Contentlet objects (LinkedHashMap) are in the records list

Key files:

  • dotCMS/src/main/java/com/dotcms/rest/MapToContentletPopulator.java
  • dotCMS/src/main/java/com/dotcms/content/elasticsearch/business/ESContentletAPIImpl.java
  • dotCMS/src/main/java/com/dotcms/rest/api/v1/workflow/WorkflowResource.java

dotCMS Version

Latest from main branch (also reproducible on current cloud environments)

Severity

Medium - Some functionality impacted

Links

NA

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.