How to find out what a template needs and why it failed
Leave feedback
On this page
Run the GroupDocs.Assembly MCP server locally and your agent can tell you what a template needs before anything is generated, and explain in plain words why it failed afterwards — a placeholder in the wrong syntax, an unclosed block, a missing field:
dnx GroupDocs.Assembly.Mcp --yes
What does order-lines.docx need, and why won’t it generate?
Note
The commands and config snippets on this page are for the .NET build of the server — the only platform available today. Installation and client setup: MCP server for .NET. Other platforms will expose the same tools with their own launch command; everything else on this page applies unchanged.
Prerequisites
The server registered in your AI client — quick start.
Two kinds of checking
get_template_fields -- static: reads the tags, generates nothing
| tags, dataSourceNames, fields, dataSkeleton, notes
| notes flag: {{...}} placeholders, unreadable binary templates
v
assemble_document -- the engine: finds what static reading cannot
| unclosed <<foreach>> ...... "Unexpected end of template"
| field missing in data ..... "The template reads 'Email', ..."
| empty list + arithmetic ... "Can not apply operator '*' ..."
v
assemble_document {"inlineErrors":true}
writes "Error! ..." into the output next to each bad tag
What the agent sees
Captured from server 26.11.0 (the evaluation note that opens each response is trimmed).
A template in another engine’s syntax (Dear {{name}}, your order {{order_id}} has shipped.):
-> get_template_fields {"template":{"filePath":"shipping-notice.docx"}}
<- { "tagCount": 0, "notes": [
"No <<…>> tags were found: this document is not a GroupDocs.Assembly
template, or its tags are in a part the server does not read (text
boxes in charts, embedded objects).",
"The template contains 2 '{{…}}' placeholder(s). GroupDocs.Assembly
does not process that syntax and leaves it as text; write <<[name]>>
instead." ] }
An unclosed block — get_template_fields lists the tags (it reads them statically); the engine finds the problem:
-> assemble_document {"template":{"filePath":"order-lines.docx"},
"dataJson":"{\"lines\":[{\"Title\":\"Cable\",\"Quantity\":2}]}"}
<- Document assembly failed for 'order-lines.docx': ... Unexpected end of
template. A block tag is not closed: every <<foreach>> needs <</foreach>>
and every <<if>> needs <</if>>.
Errors written into the output — inlineErrors: true generates anyway and marks each bad tag (here the upstream sample with << var [name]>>):
-> assemble_document {"template":{"filePath":"inline-error.docx"},
"dataJson":"{\"name\":\"x\"}","inlineErrors":true}
<- Assembled 'inline-error.docx' with inline JSON (JSON object as 'product')
as DOCX. The template has errors: each one is written into the output
next to its tag, starting with 'Error!'
The document then reads << var [name] Error! An assignment operator is expected. >>.
A binary template:
-> get_template_fields {"template":{"filePath":"contracts-table.msg"}}
<- { "readable": false, "notes": [ "Tags cannot be read from a .msg template
without generating it. Save the template as DOCX, XLSX, PPTX or EML to
inspect it, or generate it with assemble_document and inlineErrors=true
to see which fields fail." ] }
Markdown is a template too — product-readme.md reported "dataSourceNames": [ "product", "description" ] and generated a DOCX.
Expected result
Before a run: the list of data the template needs, and any syntax the engine will ignore. After a failed run: the reason in one sentence and the fix.
Troubleshooting
Symptom
Cause
Fix
“Unexpected end of template. A block tag is not closed”
a <<foreach>> or <<if>> without its closing tag
add <</foreach>> / <</if>>
“Can not apply operator ‘’ to operands of type ‘System.Object’ and ‘System.Object’”*
arithmetic over an empty list — it carries no types, even with allowMissingMembers
pass at least one item, or wrap the block in <<if [items.Any()]>>
"readable": false
a binary template (MSG, DOC, XLS, PPT)
save it as DOCX/XLSX/PPTX/EML to inspect; pass dataSourceName with array, CSV or table data
FAQ
Is the skeleton exact? It is inferred from the tags; the server says so in notes. Values computed through Select or GroupBy projections are not followed.
Why do tags in a chart not show up? Static reading skips some parts (text boxes in charts, embedded objects); the note says so. The engine still processes chart tags — see reports with charts.
Agents follow project instructions about when to use a tool. Paste this into the instruction file your agent reads (CLAUDE.md, AGENTS.md, .github/copilot-instructions.md, .cursorrules):
Before filling a template, call get_template_fields and read its notes. If
assemble_document fails, quote the server's message, fix the data or tell me
the template line to change; use inlineErrors=true only for debugging copies.
Honest limits
Evaluation mode: every generated document starts with an Evaluation Only line, workbooks gain a worksheet, and e-mail templates lose their HTML body. Licensing.
<<[name]>>, not {{name}}: other engines’ placeholders stay in the output as text.
Templates are trusted input: image and document tags load the paths and URLs their expressions return.
Dates: write them as "2026-11-12T00:00:00" and format them in the template; a date-only string can shift by a day on machines east of UTC.