AI - Content Prompt sub-action: default example prompt references nonexistent ${fieldContent} and fails
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 970
- Forks
- 486
- Avg merge
- 3d 33m
- Merged PRs (30d)
- 170
Description
Problem
The default example prompt shipped with the AI - Content Prompt workflow sub-action references ${fieldContent}, which is not a variable that exists in the Velocity context. Running the sub-action with the out-of-the-box prompt fails.
Current default (OpenAIContentPromptActionlet.java#L42):
We need an attractive search result in Google. Return a json object that includes the fields "pageTitle" for a meta title of less than 55 characters and "metaDescription" for the meta description of less than 300 characters using this content:\n\n${fieldContent}\n\n
Root cause
OpenAIContentPromptRunner.openAIRequest() evaluates the prompt with VelocityUtil.eval() against the context built by VelocityContextFactory.getMockContext(). That context provides $contentletToString, $contentMap, $dotContentMap and $contentlet — there is no fieldContent. Velocity renders the unresolved reference verbatim, so the model receives the literal string ${fieldContent} and no actual content. It replies with prose rather than JSON.
parseJsonResponse() then does:
response.substring(response.indexOf("{"), response.lastIndexOf("}") + 1)
With no { in the reply, indexOf returns -1 and lastIndexOf("}") + 1 returns 0, producing:
Unable to execute the Workflow Action. Error: Range [-1, 0) out of bounds for length 341
The default is also inconsistent with the sub-action's own getHowTo(), which correctly documents $dotContentMap. The literal \n\n in the default is a second (cosmetic) problem — it renders as backslash-n in the textarea rather than as line breaks.
Suggested fix
Update the default value to:
Return ONLY a raw JSON object — no markdown code fences, no commentary — with exactly two keys: "pageTitle" (a meta title under 55 characters) and "metaDescription" (a meta description under 300 characters), written to be an attractive Google search result for this content:
$contentletToString
Secondary
parseJsonResponse() should guard against indexOf("{") == -1 and throw BadAIJsonFormatException with a message naming the real problem (the AI did not return JSON, plus the response), instead of surfacing an opaque Range [-1, 0) error to the user.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with dotCMS/src/main/java/com/dotcms/ai/workflow/OpenAIContentPromptActionlet.java around line 42 and compare its default prompt with getHowTo(). Then inspect OpenAIContentPromptRunner.openAIRequest() and parseJsonResponse() to verify the Velocity context and malformed-response path. Done means the default uses an available content variable and non-JSON responses produce BadAIJsonFormatException instead of the Range error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100