Troubleshooting Guide
Document Won't Open in Word
Symptom: "Word found unreadable content"
Error Dialog:
"Word found unreadable content in [filename].docx. Do you want to recover the contents of this document?"
Possible Causes
- Malformed XML - Syntax errors in document.xml
- Invalid Element Nesting - Wrong hierarchy
- Missing Required Elements - Elements without required children
- Broken Relationships - Missing or invalid .rels entries
Diagnosis Steps
Step 1: Use OpenXML SDK Tool
1. Open OpenXML SDK Productivity Tool
2. File → Open → Select DOCX
3. Click "Validate"
4. Review errors in bottom panel
Step 2: Manual XML Inspection
1. Rename .docx to .zip
2. Extract contents
3. Open word/document.xml in text editor
4. Look for XML syntax errors
Common Fixes
Fix 1: Text Without Run
<!-- WRONG -->
<w:p>
<w:t>Text</w:t>
</w:p>
<!-- CORRECT -->
<w:p>
<w:r><w:t>Text</w:t></w:r>
</w:p>
Fix 2: Table in Wrong Location
<!-- WRONG -->
<w:r>
<w:tbl>...</w:tbl>
</w:r>
<!-- CORRECT -->
<w:body>
<w:tbl>...</w:tbl>
</w:body>
Fix 3: Missing Table Grid
<!-- WRONG -->
<w:tbl>
<w:tblPr>...</w:tblPr>
<w:tr>...</w:tr>
</w:tbl>
<!-- CORRECT -->
<w:tbl>
<w:tblPr>...</w:tblPr>
<w:tblGrid>
<w:gridCol w:w="5000"/>
</w:tblGrid>
<w:tr>...</w:tr>
</w:tbl>
Images Not Displaying
Symptom: Empty boxes or "X" placeholders
Possible Causes
- Missing Image File - File not in /word/media/
- Broken Relationship - Invalid relationship ID
- Incorrect Path - Wrong target in .rels file
- Corrupted Image - Invalid image data
Diagnosis Steps
Step 1: Check if Image Files Exist
1. Rename .docx to .zip
2. Open archive
3. Navigate to /word/media/
4. Verify image files present
Step 2: Check Relationships
1. Open /word/_rels/document.xml.rels
2. Find image relationships
3. Verify Target path matches actual file
Example relationship:
<Relationship Id="rId5"
Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
Target="media/image1.png"/>
Step 3: Check Image Reference in Document
<a:blip r:embed="rId5"/> <!-- Must match relationship ID -->
Common Fixes
Fix 1: Missing Image Part
// Add image to document
ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Png);
using (FileStream stream = new FileStream("image.png", FileMode.Open))
{
imagePart.FeedData(stream);
}
string relationshipId = mainPart.GetIdOfPart(imagePart);
// Use relationshipId in drawing element
Fix 2: Wrong Relationship ID
// Get correct relationship ID
string relationshipId = mainPart.GetIdOfPart(imagePart);
// Update blip reference
var blip = drawing.Descendants<Blip>().First();
blip.Embed = relationshipId;
Table Layout Issues
Symptom: Cells wrong width, text cut off
Possible Causes
- Grid/Cell Width Mismatch - Cell width doesn't match grid
- Missing gridSpan - Merged cells not defined
- Percentage vs Absolute - Mixing width types
- Cell Content Too Large - Content exceeds cell width
Diagnosis Steps
Step 1: Check Table Grid
<w:tblGrid>
<w:gridCol w:w="3000"/> <!-- Column 1: 3000 twips -->
<w:gridCol w:w="3000"/> <!-- Column 2: 3000 twips -->
</w:tblGrid>
Step 2: Check Cell Widths
<w:tc>
<w:tcPr>
<w:tcW w:w="3000" w:type="dxa"/> <!-- Must match grid -->
</w:tcPr>
...
</w:tc>
Common Fixes
Fix 1: Recalculate Cell Widths
// Total table width
int totalWidth = 5000; // twips
// Number of columns
int columnCount = 3;
// Width per column
int columnWidth = totalWidth / columnCount;
// Apply to grid
var tableGrid = new TableGrid();
for (int i = 0; i < columnCount; i++)
{
tableGrid.AppendChild(new GridColumn { Width = columnWidth.ToString() });
}
// Apply to cells
foreach (var cell in row.Elements<TableCell>())
{
var cellProps = cell.GetFirstChild<TableCellProperties>();
if (cellProps == null)
{
cellProps = new TableCellProperties();
cell.InsertAt(cellProps, 0);
}
cellProps.AppendChild(new TableCellWidth
{
Width = columnWidth.ToString(),
Type = TableWidthUnitValues.Dxa
});
}
Fix 2: Handle Merged Cells
// Cell spanning 2 columns
var mergedCell = new TableCell();
mergedCell.AppendChild(new TableCellProperties(
new TableCellWidth { Width = (columnWidth * 2).ToString(), Type = TableWidthUnitValues.Dxa },
new GridSpan { Val = 2 } // Spans 2 columns
));
Content Controls Not Working
Symptom: Fields not populating, SDT missing
Possible Causes
- Wrong SDT Type - Block vs Inline mismatch
- Missing sdtContent - No content wrapper
- Mail Merge Settings - ClearFields = true
- Syncfusion Bug - Content control flattened
Diagnosis Steps
Step 1: Check SDT Structure
<w:sdt>
<w:sdtPr>
<w:tag w:val="FieldName"/>
</w:sdtPr>
<w:sdtContent>
<!-- Content here -->
</w:sdtContent>
</w:sdt>
Step 2: Check Mail Merge Settings
// In AppraiSys pattern
DestinationDocument.MailMerge.ClearFields = false; // Don't remove fields
Common Fixes
Fix 1: Use Correct SDT Type
// Block-level (for paragraphs/tables)
var sdtBlock = new SdtBlock();
// Inline (for text within paragraph)
var sdtRun = new SdtRun();
Fix 2: Preserve Content Controls
// Before mail merge
document.MailMerge.ClearFields = false;
// Process fields
document.MailMerge.Execute(data);
// Content controls retained
Formatting Lost After Conversion
Symptom: Styles missing after DOCX → SFDT → DOCX
Possible Causes
- Styles Not Defined - Style referenced but not in styles.xml
- Syncfusion Simplification - Some formatting simplified
- Conversion Bugs - Known Syncfusion limitations
- Local Overrides Lost - Direct formatting removed
Diagnosis Steps
Step 1: Check Styles Exist
// Verify style exists
var styleExists = stylesPart.Styles.Elements<Style>()
.Any(s => s.StyleId == "Heading1");
if (!styleExists)
{
// Style missing - create it
CreateParagraphStyle(stylesPart.Styles, "Heading1", "Heading 1", 98);
}
Step 2: Compare Before/After
// Original
var originalDoc = WordprocessingDocument.Open("original.docx", false);
// After conversion
var sfdt = DocumentToSfdtFormat.Convert(originalStream);
var convertedStream = ConvertSfdtToDocx(sfdt);
var convertedDoc = WordprocessingDocument.Open(convertedStream, false);
// Compare styles
CompareStyles(originalDoc, convertedDoc);
Common Fixes
Fix 1: Re-apply Styles After Conversion
// After SFDT → DOCX conversion
using (var doc = WordprocessingDocument.Open(stream, true))
{
var mainPart = doc.MainDocumentPart;
// Ensure styles part exists
if (mainPart.StyleDefinitionsPart == null)
{
var stylesPart = mainPart.AddNewPart<StyleDefinitionsPart>();
CreateDefaultStyles(stylesPart.Styles);
}
}
Fix 2: Use Direct Formatting for Critical Elements
// Don't rely on styles for critical formatting
var run = new Run();
var runProps = new RunProperties(
new Bold(),
new FontSize { Val = "28" },
new Color { Val = "FF0000" }
);
run.AppendChild(runProps);
run.AppendChild(new Text("Critical Text"));
Validation Errors
Common Validation Messages
Error: "Attribute 'val' is required"
Meaning: Element missing required attribute
Example:
<!-- WRONG -->
<w:b/> <!-- Some elements need val attribute -->
<!-- CORRECT -->
<w:b w:val="true"/>
Fix: Add required attribute (check ECMA-376 spec)
Error: "Element X cannot be child of element Y"
Meaning: Invalid element nesting
Example:
<!-- WRONG -->
<w:p>
<w:tbl>...</w:tbl>
</w:p>
<!-- CORRECT -->
<w:body>
<w:p>...</w:p>
<w:tbl>...</w:tbl>
</w:body>
Fix: Review element hierarchy rules
Error: "Required element missing"
Meaning: Parent element missing required child
Example:
<!-- WRONG -->
<w:tc>
<!-- Missing paragraph -->
</w:tc>
<!-- CORRECT -->
<w:tc>
<w:p/> <!-- Required -->
</w:tc>
Fix: Add required child element
Performance Issues
Symptom: Document generation slow
Possible Causes
- Large Images - Uncompressed images
- Too Many Elements - Document too complex
- Inefficient Code - Repeated lookups
- Memory Leaks - Not disposing objects
Common Fixes
Fix 1: Compress Images
// Resize/compress before embedding
using (var image = Image.Load(imageBytes))
{
image.Mutate(x => x.Resize(new ResizeOptions
{
Size = new Size(800, 600),
Mode = ResizeMode.Max
}));
image.Save(outputStream, new JpegEncoder { Quality = 85 });
}
Fix 2: Batch Operations
// Instead of repeated lookups
var paragraphs = body.Elements<Paragraph>().ToList();
foreach (var para in paragraphs)
{
// Process
}
Fix 3: Dispose Properly
// AppraiSys pattern
using (var doc = new WordDocument(stream, FormatType.Docx))
{
// Process
doc.Save(outputStream, FormatType.Docx);
} // Automatically disposed
Syncfusion-Specific Issues
Issue: Extra Blank Paragraphs
Symptom: Blank paragraphs appear after conversion
Cause: Syncfusion SFDT adds spacing paragraphs
Fix: Post-process to remove empty blocks
// Remove empty paragraphs
var emptyParas = body.Elements<Paragraph>()
.Where(p => !p.Elements<Run>().Any())
.ToList();
foreach (var para in emptyParas)
{
para.Remove();
}
Issue: TOC Not Updating
Symptom: Table of contents shows placeholder text
Cause: SFDT doesn't support automatic TOC update
Fix: Update TOC after final DOCX generation
// After SFDT → DOCX
using (var doc = WordprocessingDocument.Open(stream, true))
{
// TOC must be updated in Word or via automation
// Flag TOC for update
var updateFields = new UpdateFieldsOnOpen { Val = true };
doc.MainDocumentPart.DocumentSettingsPart.Settings.Append(updateFields);
}
Issue: Image URLs Not Working
Symptom: External image URLs don't display
Cause: Syncfusion requires base64 for reliable rendering
Fix: Download and encode images (AppraiSys pattern)
// From DocumentToPdfConverter.cs
var imagesToDownload = sfdtWrapper?.Images
.Where(x => x.Value.FirstOrDefault()?.StartsWith("http") ?? false)
.ToList();
foreach (var imageUrl in imagesToDownload)
{
var bytes = await httpClient.GetByteArrayAsync(imageUrl);
var base64 = Convert.ToBase64String(bytes);
sfdtWrapper.Images[key].Insert(0,
$"data:image/png;base64,{base64}"
);
}
Debugging Checklist
Before Reporting Bug
- Validated with OpenXML SDK tool
- Checked element hierarchy
- Verified all required elements present
- Checked relationships intact
- Tested in clean Word installation
- Reproduced on another machine
- Checked AppraiSys patches applied
- Reviewed similar issues in docs
Information to Provide
- Error Message: Exact text
- Document ID: Report/template ID
- Steps to Reproduce: Detailed steps
- Expected vs Actual: What should happen vs what happens
- Validation Errors: Output from OpenXML SDK tool
- Screenshots: Visual evidence
- Sample File: Minimal example demonstrating issue
Quick Fixes Reference
| Problem | Quick Check | Quick Fix |
|---|---|---|
| Document won't open | Validate XML | Fix element hierarchy |
| Images missing | Check /word/media/ | Add image parts |
| Table layout broken | Check grid vs cells | Recalculate widths |
| Formatting lost | Check styles.xml exists | Re-create styles |
| Content control missing | Check mail merge settings | Set ClearFields = false |
| Extra blank pages | Show formatting marks | Remove empty paragraphs |
| Slow generation | Check image sizes | Compress images |
Useful Commands
Validate Document (PowerShell)
# Using OpenXML SDK
[Reflection.Assembly]::LoadFrom("C:\path\to\DocumentFormat.OpenXml.dll")
$doc = [DocumentFormat.OpenXml.Packaging.WordprocessingDocument]::Open("file.docx", $false)
$validator = New-Object DocumentFormat.OpenXml.Validation.OpenXmlValidator
$errors = $validator.Validate($doc)
$errors | ForEach-Object { Write-Host $_.Description }
$doc.Close()
Extract DOCX (Command Line)
# Extract to folder
unzip document.docx -d extracted/
# View document.xml
cat extracted/word/document.xml | xmllint --format -
Resources
- ECMA-376 Specification
- OpenXML SDK Documentation
- Syncfusion Documentation
- Stack Overflow: openxml tag
Next Steps
If issue not resolved:
- Check Common Fatal Mistakes
- Review Element Hierarchy Rules
- Consult QA Testing Workflow
- Contact development team with detailed report
💡 Remember: 90% of OOXML errors are hierarchy problems. Check THE BIG THREE first!