Troubleshooting Guide
Debug and resolve common BimlScript compilation and runtime issues.
Enable Build Logging
Logging helps identify where and why builds fail.
BimlStudio Logging
- Click Start Logging on the Build & Deploy ribbon
- View log entries in the Logging window
- Look for error entries with timestamps
Configure LoggingManager in Code
<#@ import namespace="Varigence.Utility.Logging" #>
<#
var loggingManager = new LoggingManager(Logging.LoggingMode.File) {
IsEnabled = true,
LogFilePath = @"C:\BimlLogs\build.log"
};
LoggingManager.RegisterDefaultLoggingManager(loggingManager);
#>
Logging Modes
| Mode | Purpose | Access |
|---|---|---|
| EventDriven | Real-time output in BimlStudio | Subscribe to LogMessage event |
| FullText | Complete log as string | LoggingManager.FullLog |
| List | Log entries as objects | LoggingManager.LogEvents |
| File | Write to external file | Set LogFilePath property |
Logging Detail Levels
| Level | What's Logged |
|---|---|
| Files | File compilation start/end events |
| Objects | Individual Biml object events |
| Queries | All database queries with timing |
<#
var loggingManager = new LoggingManager(Logging.LoggingMode.File) {
IsEnabled = true,
LogFilePath = @"C:\BimlLogs\build.log",
LoggingDetail = Logging.LoggingDetail.Files | Logging.LoggingDetail.Queries
};
#>
Using the Preview Pane
Preview expanded Biml before building to catch errors early.
How to Use
- Right-click the
.bimlfile in Solution Explorer - Select Expand to BimlScript or Preview Biml
- Review the generated XML for errors
What to Look For
- Malformed XML: Missing closing tags, invalid characters
- Empty collections: Loops that produce no output
- Wrong references: Connection names that don't exist
Preview Example
Source BimlScript:
<# foreach (var table in tables) { #>
<Table Name="<#= table.Name #>" />
<# } #>
Preview shows:
<Table Name="Customer" />
<Table Name="Order" />
<Table Name="Product" />
If preview is empty, your tables collection has no items.
Common Compilation Errors
Object Reference Errors
Error: Object reference not set to an instance of an object
Causes and Solutions:
| Cause | Solution |
|---|---|
| RootNode object doesn't exist yet | Use tier directive to order file compilation |
| Connection not found | Verify connection exists in a lower-tier file |
| Collection is empty | Check GetDatabaseSchema() results |
Fix with tiers:
<!-- Connections.biml - tier 10 (compiles first) -->
<#@ template tier="10" #>
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
<Connections>
<OleDbConnection Name="Source" ConnectionString="..." />
</Connections>
</Biml>
<!-- Packages.biml - tier 20 (compiles second, can reference connections) -->
<#@ template tier="20" #>
<# var conn = RootNode.OleDbConnections["Source"]; #>
Invalid XML Errors
Error: The 'X' start tag does not match the end tag of 'Y'
Common Causes:
- BimlScript output contains special characters
- Closing tags in wrong order
- Unclosed control blocks
Debug technique:
<#
// Add debugging output
System.Diagnostics.Debug.WriteLine($"Processing table: {table.Name}");
#>
Connection Not Found
Error: Cannot find connection named 'ConnectionName'
Checklist:
- Connection name matches exactly (case-sensitive)
- Connection file compiles at lower tier
- Connection uses correct element type (OleDbConnection vs AdoNetConnection)
Verify connections exist:
<#
// List all available connections
foreach (var conn in RootNode.Connections) {
System.Diagnostics.Debug.WriteLine($"Found connection: {conn.Name}");
}
#>
Import Options Issues
Error: Database import returns empty results
Common Fixes:
<#
var sourceConnection = RootNode.OleDbConnections["Source"];
// Include specific schemas only
var schemas = new List<string>{"dbo", "Sales"};
// Exclude views, foreign keys for cleaner import
var options = ImportOptions.ExcludeViews |
ImportOptions.ExcludeForeignKey |
ImportOptions.ExcludeColumnDefault;
var result = sourceConnection.GetDatabaseSchema(schemas, null, options);
// Check what was imported
System.Diagnostics.Debug.WriteLine($"Tables found: {result.TableNodes.Count()}");
#>
Custom Validation
Using ValidationReporter
Add custom validation messages during compilation:
<#@ import namespace="Varigence.Biml.Extensions" #>
<#
foreach (var table in RootNode.Tables) {
// Error: Stop compilation
if (string.IsNullOrEmpty(table.Name)) {
ValidationReporter.Report(Severity.Error,
"Table name cannot be empty",
table);
}
// Warning: Continue but alert user
if (table.Columns.Count == 0) {
ValidationReporter.Report(Severity.Warning,
$"Table {table.Name} has no columns defined",
table);
}
// Information: Just informational
if (table.GetTag("LoadType") == null) {
ValidationReporter.Report(Severity.Information,
$"Table {table.Name} missing LoadType annotation",
table);
}
}
#>
Severity Levels
| Severity | Effect |
|---|---|
| Error | Stops compilation, must fix |
| Warning | Continues compilation, should fix |
| Information | Continues compilation, optional |
Debug Utilities
GetBiml() Method
View the Biml representation of any object:
<#
foreach (var table in RootNode.Tables) {
// Output table's Biml to debug
System.Diagnostics.Debug.WriteLine(table.GetBiml());
}
#>
ObjectTag for Tracing
Add tracking information to objects:
<#@ template tier="10" #>
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
<Tables>
<Table Name="Customer" SchemaName="dbo">
<Annotations>
<Annotation Tag="Source">CRM Database</Annotation>
<Annotation Tag="Owner">Data Team</Annotation>
<Annotation Tag="LastReviewed">2024-01-15</Annotation>
</Annotations>
<Columns>
<Column Name="ID" DataType="Int32" />
</Columns>
</Table>
</Tables>
</Biml>
<!-- Later, read the tags -->
<#
var table = RootNode.Tables["Customer"];
var source = table.GetTag("Source"); // Returns "CRM Database"
#>
Conditional Compilation
Skip problematic objects during debugging:
<#
foreach (var table in RootNode.Tables) {
// Skip specific tables for debugging
if (table.Name == "ProblemTable") {
System.Diagnostics.Debug.WriteLine($"Skipping {table.Name}");
continue;
}
// Only process if enabled
if (table.GetTag("Enabled") != "false") {
#>
<Package Name="Load_<#= table.Name #>">
<!-- Package content -->
</Package>
<#
}
}
#>
Tier Ordering Issues
Understanding Tiers
Biml files compile in tier order (lowest first). Files in the same tier compile together.
Tier 10: Connections.biml
Tier 20: Tables.biml (can reference connections)
Tier 30: Packages.biml (can reference tables and connections)
Common Tier Problems
| Problem | Symptom | Solution |
|---|---|---|
| No tier specified | Random compilation order | Add <#@ template tier="X" #> |
| Reference before definition | Object not found errors | Lower tier for referenced object |
| Circular reference | Compilation fails | Reorganize into separate files |
Recommended Tier Strategy
| Tier Range | Content |
|---|---|
| 1-10 | Connections, file connections |
| 11-20 | Database schemas, tables |
| 21-30 | Stored procedures, views |
| 31-40 | Individual SSIS packages |
| 41-50 | Master workflow packages |
SSIS-Specific Issues
Data Flow Errors
Issue: Columns don't map correctly
Debug steps:
- Preview the Biml to see column definitions
- Verify source and destination column names match
- Check data type compatibility
<#
foreach (var col in table.Columns) {
System.Diagnostics.Debug.WriteLine(
$"Column: {col.Name}, Type: {col.DataType}, Length: {col.Length}"
);
}
#>
Package Won't Execute
Checklist:
- Connection strings are valid for runtime
- Table references exist in target database
- Variables are properly scoped
Quick Diagnostic Checklist
When builds fail, check in this order:
- Tier ordering: Are files compiling in correct order?
- Connection names: Exact match, case-sensitive?
- Empty collections: Does
GetDatabaseSchema()return data? - XML validity: Use Preview to see expanded Biml
- Syntax errors: Check for unclosed nuggets
<# ... #> - Import namespaces: All required
<#@ import ...#>present?
Next Steps
- Common Patterns - Reusable solutions
- Biml Basics - Core syntax reference
- Introduction to BimlScript - Code nuggets and directives