Quick solutions to common problems when developing WATS converters.
Symptoms:
Test run for YourConverter.Tests.dll (.NET 8.0)
No tests found.
Cause: File extension pattern doesn't match your test files.
Solution:
-
Check your test files exist:
ls tests/Data/
-
Open
tests/ConverterTests.csand findGetTestFiles()method (around line 100-110) -
Update the file pattern:
// If your files are .tdr, change from: var files = Directory.GetFiles(dataDir, "*.log", SearchOption.AllDirectories) // To: var files = Directory.GetFiles(dataDir, "*.tdr", SearchOption.AllDirectories)
-
Rebuild and test:
dotnet build dotnet test --list-tests # Should now show your tests
Tip: To support any file extension:
var files = Directory.GetFiles(dataDir, "*.*", SearchOption.AllDirectories)
.Where(f => !f.EndsWith(".md") && !f.EndsWith(".json"))
.ToArray();Symptoms:
DirectoryNotFoundException: Data directory not found: C:\...\bin\Debug\net8.0\Data
Cause: Test files not copied to output directory, or Data folder missing.
Solution:
-
Verify Data folder exists:
YourConverter/tests/Data/ -
Check
.csprojincludes this configuration:<ItemGroup> <None Update="Data\**\*"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup>
-
Rebuild:
dotnet clean dotnet build -
Verify files copied:
ls tests/bin/Debug/net8.0/Data/
Error:
error CS0234: The type or namespace name 'Abstracts' does not exist in
the namespace 'Xunit' (are you missing an assembly reference?)
Cause: Typo in using statement - should be Xunit.Abstractions (with "ions")
Solution:
Open tests/ConverterTests.cs and fix:
// WRONG:
using Xunit.Abstracts;
// CORRECT:
using Xunit.Abstractions;Error:
error CS1501: No overload for method 'InitializeAPI' takes 0 arguments
Cause: Missing required boolean parameter.
Solution:
// WRONG:
api.InitializeAPI();
// CORRECT:
api.InitializeAPI(true);Note: InitializeAPI(true) enables mock mode or connects to WATS Client depending on context.
Error:
error CS1503: Argument 1: cannot convert from 'int' to 'short'
Cause: TestSocketIndex expects short, not int.
Solution:
// WRONG:
genealogyItem.TestSocketIndex = 1;
// CORRECT:
genealogyItem.TestSocketIndex = (short)1;
// or
genealogyItem.TestSocketIndex = 1; // Implicit conversion works in most casesError:
error CS1061: 'TDM' does not contain a definition for 'AddPartInfo'
Cause: Wrong method name - API uses AddUUTPartInfo not AddPartInfo.
Solution:
// WRONG:
api.AddPartInfo(partInfo);
// CORRECT:
uut.AddUUTPartInfo(partInfo); // Note: called on the UUTReport, not TDMError during test:
Exception: Operation type with code '30' not found on WATS server!
Check Control Panel → Process & Production → Processes
Cause: Operation type code doesn't exist on your WATS server.
Solutions:
Option 1: Use ValidateOnly mode (no server required)
// tests/TestConfig.json
{
"activeMode": "ValidateOnly",
"modes": {
"ValidateOnly": {
"mockApi": true, // ← Set to true
"submit": false
}
}
}Option 2: Use correct operation code for your server
// In your converter or TestConfig.json
parameters["operationTypeCode"] = "10"; // SW-Debug (usually exists)Option 3: Get valid codes from your server
# Use GetOperationTypes tool
cd Tools/GetOperationTypes
dotnet runError:
Exception: Genealogy item must have location information.
Cause: Must set EITHER UUTPosition OR TestSocketIndex.
Solution:
// Option 1: Use UUTPosition (recommended)
genealogyItem.UUTPosition = "1";
// Option 2: Use TestSocketIndex
genealogyItem.TestSocketIndex = (short)1;
// Option 3: Use both (for multi-socket scenarios)
genealogyItem.UUTPosition = "A1";
genealogyItem.TestSocketIndex = (short)1;Symptoms:
NullReferenceException: Object reference not set to an instance of an object
at YourConverter.ImportReport(TDM api, Stream file)
Common Causes:
-
Parsing returned null:
// Always validate parsing results string serialNumber = ExtractSerialNumber(content); if (string.IsNullOrEmpty(serialNumber)) throw new Exception("Serial number not found in file");
-
API object not initialized:
// Check operation type exists before using if (operationType == null) throw new Exception($"Operation type '{opCode}' not found");
-
File content is empty:
string content = reader.ReadToEnd(); if (string.IsNullOrWhiteSpace(content)) throw new Exception("File is empty or unreadable");
Error: Tests hang or fail when calling api.InitializeAPI() inside ImportReport().
Cause: API is already initialized by the test framework.
Solution:
// WRONG: Don't initialize API in your converter
public Report ImportReport(TDM api, Stream file)
{
api.InitializeAPI(true); // ❌ NEVER DO THIS
// ...
}
// CORRECT: API is already initialized by caller
public Report ImportReport(TDM api, Stream file)
{
// Use api directly - it's ready to use
var operationType = api.GetOperationType(code);
// ...
}Note: Only initialize API in test methods (CreateMockApi(), CreateRealApi()), never in the converter itself.
Symptoms: Operation type not found even though code is correct.
Causes & Solutions:
-
Using Mock API:
// Mock API may not return operation types // Solution: Use ValidateOnly mode or don't check operation types in tests { "activeMode": "ValidateOnly", "modes": { "ValidateOnly": { "mockApi": true, // ← Mock API has limited functionality "submit": false } } }
-
Not connected to WATS server:
// For testing against real server, use: { "activeMode": "SubmitToDebug", "modes": { "SubmitToDebug": { "mockApi": false, // ← Real API connection "submit": true, "forceOperationCode": "10" } } }
Error:
ValidationException: SerialNumber exceeds maximum length of 50 characters
Cause: String property too long for WATS database schema.
Solutions:
-
Enable AutoTruncate (recommended):
public Report ImportReport(TDM api, Stream file) { api.ValidationMode = ValidationModeType.AutoTruncate; // Add this // Now strings will be automatically truncated to fit }
-
Manually truncate:
string serialNumber = ExtractSerialNumber(content); if (serialNumber.Length > 50) serialNumber = serialNumber.Substring(0, 50);
Error when deploying to WATS Client:
FileNotFoundException: Could not load file or assembly
'Virinco.WATS.Interface, Version=...'
Cause: Wrong NuGet package for deployment target.
Solution:
Check your target framework:
For .NET Framework 4.8 (WATS Client 5.x/6.x):
<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
<PackageReference Include="WATS.Client" Version="6.1.*" />
</ItemGroup>Deploy: bin/Release/net48/YourConverter.dll
For .NET 8.0 (WATS Client 7.x):
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="Virinco.WATS.ClientAPI" Version="7.0.*" />
</ItemGroup>Deploy: bin/Release/net8.0/YourConverter.dll
Symptoms: DLL deployed but converter doesn't show up in WATS Client configuration.
Checklist:
-
✅ Implements correct interface:
public class YourConverter : IReportConverter_v2 // ← Must be v2
-
✅ DLL in correct location:
- Usually:
C:\Program Files (x86)\Virinco\WATS Client\Converters\
- Usually:
-
✅ Correct .NET version:
- WATS Client 5.x/6.x: Deploy
net48build - WATS Client 7.x: Deploy
net8.0build
- WATS Client 5.x/6.x: Deploy
-
✅ No compilation errors:
dotnet build --configuration Release # Check for any warnings or errors
-
✅ Restart WATS Client after deploying DLL
Symptoms: Tests take minutes to run on small files.
Common Causes:
-
Reading file multiple times:
// SLOW: Multiple reads using (var reader = new StreamReader(file)) { var header = ParseHeader(reader); // Reads part of file var steps = ParseSteps(reader); // Can't read - stream is consumed } // FAST: Read once into memory using (var reader = new StreamReader(file)) { string content = reader.ReadToEnd(); // Read once var header = ParseHeader(content); // Parse in memory var steps = ParseSteps(content); // Parse in memory }
-
Inefficient regex:
// SLOW: Compiling regex each time foreach (var line in lines) { var match = Regex.Match(line, @"pattern"); // Compiles every iteration } // FAST: Compile once, reuse private static readonly Regex Pattern = new Regex(@"pattern", RegexOptions.Compiled); foreach (var line in lines) { var match = Pattern.Match(line); // Reuses compiled regex }
If your issue isn't listed here:
- 📖 Check API Documentation
- 📖 Review Converter Guide
- 📖 See Testing Documentation
- 🔍 Search Issues.md for known issues
- 🐛 Create detailed bug report with:
- Error message (full stack trace)
- Code snippet
- Sample test file (if possible)
- Environment (.NET version, WATS version)
Still stuck? Remember: Most issues are one of these three:
- 🔧 File extension pattern mismatch
- 🔧 Missing or wrong API parameter
- 🔧 Validation/length constraints
Check these first! 🎯