Word Connector Templates¶
Everything needed to understand, modify, and troubleshoot Word Connector document templates for Versaa forms.
How Word Connector Field Bindings Work¶
Each merge field in a Word Connector .docx template is bound to a form field via a server-side GUID registry. When you open the template in Word and click "Save to Server", the Word Connector add-in writes a manifest into the document's customXml/item1.xml (stored as UTF-16 LE) and registers the bindings server-side.
The binding record looks like:
This FieldName:GUID pair appears in:
1. word/document.xml — as the descr attribute on every merge field drawing placeholder (appears twice per field — once on <wp:docPr> and once on <pic:cNvPr>)
2. customXml/item1.xml — as <InternalName>FieldName:GUID</InternalName> entries
Critical: The GUID is assigned by the server at "Save to Server" time. You cannot fabricate or copy GUIDs from scratch — they must be obtained by opening the template in Word and registering via the Server Connection UI.
Correct Procedure to Change a Field Binding¶
Do NOT patch word/document.xml or item1.xml with random GUIDs. The correct workflow is:
- Open the
.docxin Microsoft Word with the Aareon Word Connector add-in installed - Click Server Connection in the Word Connector ribbon
- Connect to the target environment (e.g., PrtyDev)
- For each field you want to re-bind: click the placeholder image in the document → select the new field name from the Word Connector panel
- Click Save to Server
- The add-in rewrites
customXml/item1.xmland updatesword/document.xmlwith the correct FieldName:GUID pairs
To change only the field name (keeping the same GUID — e.g., renaming InstallDate → z_InstallDate_Fmt because the GUID was registered for a field that no longer changes):
- You CAN patch word/document.xml and customXml/item1.xml directly, replacing only the name portion before the colon, keeping the GUID unchanged
- Build the patched .docx by cloning the working original byte-for-byte (see below)
Safe .docx Patching via PowerShell¶
Always clone from the known-working original. Never build from a Python-constructed base or from scratch — they produce different internal structures that break the server-side renderer.
Add-Type -AssemblyName System.IO.Compression.FileSystem
$origPath = "C:\path\to\Component Replacement Request.docx" # working original
$v3Path = "C:\path\to\Component Replacement Request_V3.docx"
if (Test-Path $v3Path) { Remove-Item $v3Path -Force }
# Read all entries from original into memory
$origZip = [System.IO.Compression.ZipFile]::OpenRead($origPath)
$entries = @{}
foreach ($entry in $origZip.Entries) {
$ms = New-Object System.IO.MemoryStream
$entry.Open().CopyTo($ms)
$entries[$entry.FullName] = $ms.ToArray()
}
$origZip.Dispose()
# Patch word/document.xml (UTF-8) — rename field, keep GUID
$docXml = [System.Text.Encoding]::UTF8.GetString($entries["word/document.xml"])
$docXml = $docXml.Replace('InstallDate:6592f741-d7c4-4575-b903-01f0a53475aa',
'z_InstallDate_Fmt:6592f741-d7c4-4575-b903-01f0a53475aa')
$entries["word/document.xml"] = [System.Text.Encoding]::UTF8.GetBytes($docXml)
# Patch customXml/item1.xml (UTF-16 LE with BOM — bytes 0xFF 0xFE at start)
$rawBytes = $entries["customXml/item1.xml"]
$xmlText = [System.Text.Encoding]::Unicode.GetString($rawBytes, 2, $rawBytes.Length - 2)
$xmlText = $xmlText.Replace('InstallDate:6592f741-d7c4-4575-b903-01f0a53475aa',
'z_InstallDate_Fmt:6592f741-d7c4-4575-b903-01f0a53475aa')
$patchedBytes = [System.Text.Encoding]::Unicode.GetBytes($xmlText)
$bom = [byte[]](0xFF, 0xFE)
$combined = New-Object byte[] ($bom.Length + $patchedBytes.Length)
[Array]::Copy($bom, 0, $combined, 0, $bom.Length)
[Array]::Copy($patchedBytes, 0, $combined, $bom.Length, $patchedBytes.Length)
$entries["customXml/item1.xml"] = $combined
# Write all entries to new docx
$v3Zip = [System.IO.Compression.ZipFile]::Open($v3Path, [System.IO.Compression.ZipArchiveMode]::Create)
foreach ($key in $entries.Keys) {
$e = $v3Zip.CreateEntry($key)
$s = $e.Open()
$b = $entries[$key]
$s.Write($b, 0, $b.Length)
$s.Dispose()
}
$v3Zip.Dispose()
Verify the patch:
$chk = [System.IO.Compression.ZipFile]::OpenRead($v3Path)
# Entry count must match original exactly — no extra files
$chk.Entries.Count
# Check descr attributes
$e = $chk.Entries | Where-Object { $_.FullName -eq "word/document.xml" }
$sr = New-Object System.IO.StreamReader($e.Open())
$doc = $sr.ReadToEnd(); $sr.Dispose()
[regex]::Matches($doc, 'descr="[^"]*"') | ForEach-Object { $_.Value }
$chk.Dispose()
availableForDocumentRendering — Critical Property¶
Every FormItem that appears as a merge field in the Word Connector template must have:
What happens when it is False:
1. The Word Connector add-in shows: "N invalid display items" when you open the Server Connection panel
2. If you click "Save to Server" anyway, the server-side renderer flags those fields as invalid
3. On next form submission, document generation fails silently — emails stop arriving
4. Reverting to the previous template (which had only valid fields) immediately restores email delivery
How to fix: Set availableForDocumentRendering=True in the form XML for every field used in the template, rebuild the ftpackage, import it, then re-open the template in Word → Server Connection → confirm 0 invalid items → Save to Server.
Fields that commonly need this fixed¶
When adding new fields to a CRR-type form via XML patch, the default is False. Always explicitly set it True for any field that will appear in the document template.
archivable — Required for Formula Values to Reach the Document¶
The Word Connector server-side renderer reads field values from the task XML (stored in Task.Task.TaskXml). It does NOT re-evaluate formulas at render time.
This means: if a FormItem has a Value formula but archivable=False, the computed value is never saved to the task XML, so the renderer falls back to the raw underlying field (e.g., the original dateTime field with 00:00:00).
Rule: Any FormItem whose value is used in the document template must have archivable=True.
This is especially important for z_* String helper fields used to format dates for the document.
Decorative Images — Do Not Rename¶
Some drawing placeholders in the template have an empty field name: descr=":UUID" (colon but no name before it). These are decorative images (e.g., group start/end markers). Do not add a field name to them. The connector handles them by position; adding a name removes them from the positional list and causes a null reference crash in RangeInGroups.
CRR Template Field GUID Map (V3 — current)¶
These are the FieldName:GUID bindings in Component Replacement Request_V3.docx / Component Replacement Request.docx (original working template):
| Field Name | GUID | Notes |
|---|---|---|
Form Started |
a7bb487f-5be0-4982-bbbc-531f68199390 |
|
Form Completed |
4d40dc59-9fb2-420f-8a82-34e8b8d9bdbf |
|
User Name |
ab6679ed-130a-45ef-aa53-008d40da0413 |
|
ComponentToUpdate |
26f462fb-2aab-4c59-bd43-5c3d6e2f7a3c |
|
z_InstallDate_Fmt |
6592f741-d7c4-4575-b903-01f0a53475aa |
Was InstallDate in original |
z_NextDate_Fmt |
758aec09-df11-4d99-99b6-f932c72f90c9 |
Was NextDate in original |
z_NextPlannedDate_Fmt |
6e016603-498c-42fb-8f78-5d50ccdf6323 |
Was NextPlannedDate in original |
ActualLifecycle |
1a1c6d2f-ce40-4031-94b7-35781d9eec4e |
|
LifeSpan |
8940e0be-12b3-4e34-b61f-a8a330be4a44 |
|
PercentthroughLife |
493b6174-4c38-4941-b3ee-3a538035e1ea |
|
Detail_Description |
ddbc365d-9d7e-4dc8-8734-72789cfcca93 |
|
Recharge |
810bee26-3579-4849-b933-2525d19db5f1 |
|
Make_Safe |
1d10505e-0131-4e77-b341-64eef8916ff0 |
|
Component_In_Place |
ebfb3474-b549-43c1-a455-d758be553a45 |
In item1.xml only; no drawing in document.xml |
| (decorative) | c35fa0d7-5e96-43ba-91d3-d01dfd22d683 |
Empty name — do not rename |
Photo_Description |
bc593e3b-3309-4888-890c-639c41b38e8b |
|
Photo |
d758ce7b-076b-482f-a0a7-bb1c00db82d4 |
|
| (decorative) | 76300b16-f9c7-42cf-806c-25479b88015c |
Empty name — do not rename |
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
| "N invalid display items" in Word Connector | Fields in template have availableForDocumentRendering=False |
Set True in form XML, rebuild package, re-import, re-save template |
| Emails stop after saving new template to server | Same as above — server renderer rejects the template | Revert to previous working template; fix the form first |
Date shows as 01/04/1984 00:00:00 in PDF |
Template bound to raw dateTime field, not the formatted z_* String field |
Ensure z_* helper fields are archivable=True; bind template to z_* fields |
z_* field appears in task XML but with wrong value (e.g. "Mon") |
Formula used GetSelectedItemValue which returns a JS Date object; String(Date).split(" ")[0] = day of week |
Use $formItem.DateField.getDate() etc. instead |
z_* field is empty in task XML |
Formula used wrong column name in GetSelectedItemValue, or archivable=False |
Check column name; confirm archivable=True |
| Import error 8152: String or binary data would be truncated | Formula Expression text exceeds ~178 char SQL column limit | Shorten the expression |
| "N foreign DisplayItems… copied in from another document" on Save-to-Server (all fields rejected as "not in form definition") | The template's document.xml was re-serialised programmatically (e.g. lxml tostring) — Word Connector only trusts fields inserted via its ribbon, so a rebuilt doc is "foreign". |
Workaround (verified, Void Survey 11/06/2026): open the rebuilt doc → copy all → open a blank Word doc → Word Connector load the template from the server → delete all → paste → Save. Pasting into a server-loaded doc re-natives the fields. (Build/redesign the doc programmatically all you like, then land it with this paste step.) |
Report email attachment has no .pdf extension (Windows won't auto-open; "open with Adobe") |
The email step (SendSecureEmailWithAttachedDocument, attatchmentName) reads a form item like Form_DocumentEmailAttachmentName whose value formula defines a Calc1 = <DocName> + '.pdf' calculation but whose final Summary outputs the raw doc-name item (no extension). |
Repoint the Summary to the calc: <Value type="FormItem">Form_DocumentName</Value> → <Value type="Calculation">Calc1</Value>. (Void Survey 11/06/2026 — folded into v32.) Keep the repository-title item itself extension-less. |