Documentation

how-to/troubleshoot-issues.md

Troubleshooting Guide

This guide covers common issues you might encounter when working with the Acsis Core Polylith architecture and their solutions.

🔍 Quick Diagnosis

Is this a Component Loading Issue?

Symptoms:

  • Application starts but features don't work
  • Null reference exceptions when using component APIs
  • Missing functionality at runtime

Quick Check:

# Check if component DLLs exist
ls -la bin/components/

# Check AppHost logs for component loading
dotnet run --project projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/ | grep "ComponentLoader"

Is this a Build/Reference Issue?

Symptoms:

  • Build fails with "type or namespace not found"
  • ACSIS0001 analyzer errors
  • Project reference errors

Quick Check:

# Clean and rebuild everything
dotnet clean acsis-core.slnx
dotnet build acsis-core.slnx --verbosity normal

Is this a Runtime Configuration Issue?

Symptoms:

  • Application crashes on startup
  • Database connection errors
  • Missing configuration values

Quick Check:

# Check configuration files exist
ls -la projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/appsettings*.json

# Run with detailed logging
ASPNETCORE_ENVIRONMENT=Development dotnet run --project projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/

🔧 Component Loading Issues

Problem: Component Not Loading

Error Messages:

Warning: No implementation found for IMyComponentApi

Root Causes & Solutions:

1. Component DLL Missing from bin/components/

Check:

ls -la bin/components/ | grep MyComponent

Solution:

# Rebuild the specific component
dotnet clean engines/my-component/src/Acsis.MyComponent/
dotnet build engines/my-component/src/Acsis.MyComponent/

# Verify DLL was copied
ls -la bin/components/Acsis.MyComponent.*

2. Component Not Registered in Foundation Base

Check:

grep -r "IMyComponentApi" projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/Program.cs

Solution:

// Add to Program.cs
services.LoadComponents(
    typeof(ICoreDataApi),
    typeof(IMyComponentApi), // Add this line
    // ... other components
);

3. Component Class Doesn't Implement Interface

Check:

// Verify in implementation project
public sealed class MyComponentApi : IMyComponentApi // Must implement interface

Solution:

// Fix implementation
public sealed class MyComponentApi : IMyComponentApi {
    // Implement all interface members
    public async Task<string> DoSomethingAsync() {
        throw new NotImplementedException();
    }
}

4. Assembly Loading Exception

Enable Detailed Logging:

// In Program.cs, add:
builder.Logging.SetMinimumLevel(LogLevel.Debug);

Common Fixes:

  • Check for missing dependencies
  • Verify .NET version compatibility
  • Check for assembly version conflicts

Problem: Circular Component Dependencies

Error Messages:

Could not load file or assembly 'Acsis.ComponentA'
Circular dependency detected

Diagnosis:

# Analyze component dependencies
find engines/ -name "*.csproj" -exec grep -l "ProjectReference" {} \; | xargs grep "ProjectReference"

Solutions:

  1. Move shared models to core-data:

    // Instead of ComponentA referencing ComponentB's models
    // Move shared models to Acsis.Dynaplex.Engines.CoreData.Spec
    
  2. Use events for communication:

    // Instead of direct dependencies, use event publishing
    await _eventsApi.PublishAsync(new ComponentAEvent { ... });
    
  3. Create shared component:

    # Create new component for shared functionality
    mkdir -p engines/shared-models/src/Acsis.SharedModels.Spec/
    

🏗️ Build Issues

Problem: ACSIS0001 Analyzer Errors

Error Messages:

Error ACSIS0001: Assembly 'Acsis.Dynaplex.Projects.BbuRfid' references assembly 'Acsis.Dynaplex.Engines.CoreData'.
Only specification assemblies (.Spec) may be referenced across bricks.

Solution:

// ❌ Wrong - referencing implementation
using Acsis.Dynaplex.Engines.CoreData;

// ✅ Correct - reference specification only


Suppression (use sparingly):

#pragma warning disable ACSIS0001
using Acsis.Dynaplex.Engines.CoreData; // Documented exceptional case
#pragma warning restore ACSIS0001

Problem: Project Reference Not Found

Error Messages:

The project file 'path/to/project.csproj' does not exist

Diagnosis:

# Check if property is defined in Directory.Build.props
grep -r "MyComponentSpec" Directory.Build.props

# Check if project file exists
ls -la "$(eval echo $MyComponentSpec)" # Replace with actual path

Solutions:

  1. Add to Directory.Build.props:

    <PropertyGroup>
      <MyComponentSpec>$(EnginesRoot)my-component/src/Acsis.MyComponent.Spec/Acsis.MyComponent.Spec.csproj</MyComponentSpec>
    </PropertyGroup>
    
  2. Fix project path:

    # Find correct path
    find . -name "Acsis.MyComponent.Spec.csproj"
    
  3. Create missing project:

    mkdir -p engines/my-component/src/Acsis.MyComponent.Spec/
    # Create .csproj file
    

Problem: Build Hangs or Takes Very Long

Diagnosis:

# Build with detailed logging to see where it hangs
dotnet build acsis-core.slnx --verbosity detailed > build.log 2>&1

# Check for circular references
dotnet build acsis-core.slnx --graph

Solutions:

  1. Clean build:

    dotnet clean acsis-core.slnx
    rm -rf bin/ */bin/ */*/bin/
    dotnet build acsis-core.slnx
    
  2. Parallel build issues:

    # Disable parallel building temporarily
    dotnet build acsis-core.slnx --maxcpucount:1
    
  3. MSBuild cache issues:

    # Clear MSBuild cache
    dotnet build-server shutdown
    dotnet nuget locals all --clear
    

🚀 Runtime Issues

Problem: Application Won't Start

Error Messages:

Unhandled exception. System.TypeLoadException: Could not load type

Diagnosis:

# Check foundation base configuration
cat projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/appsettings.json

# Run with detailed startup logging
ASPNETCORE_ENVIRONMENT=Development \
DOTNET_ENVIRONMENT=Development \
dotnet run --project projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/

Common Fixes:

  1. Missing configuration:

    {
      "ConnectionStrings": {
        "DefaultConnection": "Server=localhost;Database=AcsisCore;Trusted_Connection=true;"
      }
    }
    
  2. Component loading failure:

    # Check component directory exists and has files
    ls -la projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/bin/Debug/net9.0/
    
  3. Database not available:

    # Test database connection
    sqlcmd -S localhost -E -Q "SELECT 1"
    

Problem: Null Reference Exceptions

Error Messages:

System.NullReferenceException: Object reference not set to an instance of an object
   at MyController.DoSomething() line 42

Diagnosis:

// Check if component was injected properly
public class MyController {
    private readonly IMyComponentApi _myComponent;

    public MyController(IMyComponentApi myComponent) {
        _myComponent = myComponent ?? throw new ArgumentNullException(nameof(myComponent));
        // ^^ Add null check to catch DI issues early
    }
}

Solutions:

  1. Verify component registration:

    grep -r "IMyComponentApi" projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/Program.cs
    
  2. Check component loading logs:

    info: Acsis.Dynaplex.Projects.BbuRfid.ComponentLoader[0]
          Registering IMyComponentApi
    info: Acsis.Dynaplex.Projects.BbuRfid.ComponentLoader[0]
          Registered MyComponentApi for IMyComponentApi
    
  3. Verify DI registration:

    // In a controller or service, inject IServiceProvider to debug
    public void Debug(IServiceProvider services) {
        var component = services.GetService<IMyComponentApi>();
        if (component == null) {
            // Component not registered
        }
    }
    

🎨 UI Development Issues

Problem: Next.js App Won't Start

Error Messages:

Error: Cannot find module 'next'
npm ERR! missing script: dev

Solutions:

  1. Install dependencies:

    cd engines/assettrak-ui/src/assettrak-ui/
    npm install
    
  2. Node version issues:

    # Check Node version (should be 18+)
    node --version
    
    # Use nvm if needed
    nvm use 18
    nvm install 18
    
  3. Clear npm cache:

    npm cache clean --force
    rm -rf node_modules/
    npm install
    

Problem: UI Can't Connect to API

Error Messages:

Network Error: Connection failed
CORS policy error

Solutions:

  1. Check API is running:

    curl https://localhost:7001/api/health
    
  2. CORS configuration:

    // In Program.cs
    builder.Services.AddCors(options => {
        options.AddDefaultPolicy(builder => {
            builder.WithOrigins("http://localhost:3000")
                   .AllowAnyHeader()
                   .AllowAnyMethod();
        });
    });
    
  3. Check API URL configuration:

    // In Next.js config
    const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'https://localhost:7001';
    

🗄️ Database Issues

Problem: Database Connection Failures

Error Messages:

System.Data.SqlClient.SqlException: A network-related or instance-specific error occurred

Diagnosis:

# Test SQL Server connection
sqlcmd -S localhost -E -Q "SELECT GETDATE()"

# Check connection string
grep -r "ConnectionString" projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/appsettings*.json

Solutions:

  1. Start SQL Server:

    # Windows
    net start mssqlserver
    
    # Docker
    docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=YourPassword123!" -p 1433:1433 mcr.microsoft.com/mssql/server:2022-latest
    
  2. Fix connection string:

    {
      "ConnectionStrings": {
        "DefaultConnection": "Server=localhost;Database=AcsisCore;Trusted_Connection=true;"
      }
    }
    
  3. Create database:

    CREATE DATABASE AcsisCore;
    

Problem: Entity Framework Migrations

Dynaplex uses dedicated .Database projects for EF Core migrations (see ADR-036). This section covers common migration issues.

Error: Unable to create an object of type DbContext

Error Messages:

Unable to create an object of type 'IdentityDb'
No parameterless constructor defined for this object

Root Cause: EF Core tooling can't instantiate DbContext during design-time operations.

Solutions:

  1. Check for design-time factory (should exist in all .Database projects):

    // In Acsis.Dynaplex.Engines.Identity.Database/IdentityDbFactory.cs
    public class IdentityDbFactory : IDesignTimeDbContextFactory<IdentityDb> {
        public IdentityDb CreateDbContext(string[] args) {
            var optionsBuilder = new DbContextOptionsBuilder<IdentityDb>();
            optionsBuilder.UseNpgsql("Host=localhost;Database=acsis;Username=postgres;Password=postgres");
            return new IdentityDb(optionsBuilder.Options);
        }
    }
    
  2. Use dplx CLI instead of direct dotnet ef:

    # ✅ CORRECT - Uses proper project references
    dplx db migrations add -c identity -n AddUserEmail
    
    # ❌ WRONG - May reference wrong project
    dotnet ef migrations add AddUserEmail --project engines/identity/...
    

Error: Pending Model Changes Not Detected

Error Messages:

dplx db migrations check
❌ Component 'identity' has pending model changes

Diagnosis:

# Check for pending changes manually
cd engines/identity/src/Acsis.Dynaplex.Engines.Identity.Database
dotnet ef migrations has-pending-model-changes

# Exit code 1 = pending changes
# Exit code 0 = no changes
echo $?

Solutions:

  1. Create the migration:

    dplx db migrations add -c identity -n DescribeYourChanges
    
  2. If auto-migration is enabled but not working:

    # Check if AutoMigration.targets is imported
    grep "AutoMigration.targets" Directory.Build.props
    
    # Check if disabled via environment variable
    echo $DISABLE_AUTO_MIGRATION
    
    # Manually trigger if needed
    dotnet build engines/identity/src/Acsis.Dynaplex.Engines.Identity.Database/
    

Error: Passport FK Configuration Missing

Error Messages:

The entity type 'Passport' requires a primary key to be defined
Cannot create a relationship between 'User' and 'Passport' because 'Passport' is not configured

Root Cause: Foreign key to Passport table not configured in DbContext (required pattern for Dynaplex).

Solution:

// In IdentityDb.cs
protected override void OnModelCreating(ModelBuilder modelBuilder) {
    modelBuilder.HasDefaultSchema(SCHEMA);
    base.OnModelCreating(modelBuilder);

    // Configure Passport as external reference
    modelBuilder.Entity<Passport>(b => {
        b.ToTable(Passport.TABLE_NAME, PrismDb.SCHEMA_NAME, t => t.ExcludeFromMigrations());
        b.HasKey(x => x.GlobalId);
        b.Property(x => x.GlobalId).HasColumnName("global_id");
    });

    // Configure FK for each entity
    modelBuilder.Entity<User>(b => {
        b.HasOne<Passport>()
            .WithOne()
            .HasForeignKey<User>(x => x.Id)
            .OnDelete(DeleteBehavior.Restrict)
            .HasConstraintName($"fk__{SCHEMA}__{User.TABLE_NAME}__{PrismDb.SCHEMA_NAME}__{Passport.TABLE_NAME}__id");
    });
}

Error: DateTimeOffset vs DateTime

Error Messages:

Cannot write DateTime with Kind=Unspecified to PostgreSQL type 'timestamp with time zone'
The CLR type 'DateTimeOffset' isn't natively supported by Npgsql or your PostgreSQL

Root Cause: Dynaplex uses PostgreSQL which requires DateTime (not DateTimeOffset) for timestamps.

Solution:

// ❌ WRONG - DateTimeOffset doesn't work with PostgreSQL in Dynaplex
public DateTimeOffset CreatedAt { get; set; }

// ✅ CORRECT - Use DateTime
public DateTime CreatedAt { get; set; }

// In entity configuration
builder.Property(e => e.CreatedAt)
    .HasColumnType("timestamp without time zone")
    .HasDefaultValueSql("CURRENT_TIMESTAMP");

Migration Code Fix:

// If you need to fix existing migration
migrationBuilder.AlterColumn<DateTime>(
    name: "created_at",
    schema: "identity",
    table: "users",
    type: "timestamp without time zone",
    nullable: false,
    oldClrType: typeof(DateTimeOffset),
    oldType: "timestamp with time zone");

Error: PostgreSQL Enum Mapping (Npgsql 8+)

Error Messages:

Reading as 'System.Int32' is not supported for fields having DataTypeName '...'
Reading and writing unmapped enums requires an explicit opt-in; call 'EnableUnmappedTypes'

Root Cause: PostgreSQL enum types must be mapped for both EF Core and Npgsql. Dynaplex handles this automatically, but only when the enum is properly annotated.

Solution:

using NpgsqlTypes;
using System.Text.Json.Serialization;

[JsonConverter(typeof(JsonStringEnumConverter))]
[PgName("catalog.enforced_uniqueness_level")]
public enum EnforcedUniquenessLevel {
	[PgName("none")] None,
	[PgName("item_category")] ItemCategory,
	[PgName("item_type")] ItemType
}
// Entity property should use the PostgreSQL enum column type.
[Column("enforced_uniqueness_level", TypeName = "catalog.enforced_uniqueness_level")]
public EnforcedUniquenessLevel EnforcedUniquenessLevel { get; set; }

Notes:

  • Use builder.AddAcsisDbContext<TContext>(...) so enum mappings are applied automatically.
  • Do not add per-component NpgsqlConnection.GlobalTypeMapper calls; they are not used by Aspire data sources.

Error: Migration Naming Convention

Error Messages:

Warning: Migration name doesn't follow conventions

Dynaplex Convention: Use PascalCase descriptive names.

Examples:

# ✅ GOOD
dplx db migrations add -c identity -n AddUserEmailVerification
dplx db migrations add -c identity -n UpdateUserPasswordHashColumn

# ❌ BAD
dplx db migrations add -c identity -n migration1
dplx db migrations add -c identity -n update
dplx db migrations add -c identity -n add_user_email  # snake_case

Auto-Generated Migrations:
If using optional auto-migration system, names are timestamps:

Auto_20251029143022  # Format: Auto_yyyyMMddHHmmss

Error: Cross-Schema FK Issues

Error Messages:

Cannot create FK constraint referencing table in different schema
Multiple cascade paths detected

Root Cause: Complex FK relationships across components (schemas).

Solutions:

  1. Use ExcludeFromMigrations for external entities:

    // In BbuDb.cs referencing Spatial.Location
    modelBuilder.Entity<Location>(b => {
        b.ToTable(Location.TABLE_NAME, SpatialDb.SCHEMA_NAME,
            t => t.ExcludeFromMigrations());
        b.HasKey(x => x.Id);
    });
    
  2. Configure FK explicitly:

    modelBuilder.Entity<Asset>(b => {
        b.HasOne<Location>()
            .WithMany()
            .HasForeignKey(x => x.LocationId)
            .OnDelete(DeleteBehavior.Restrict)  // Use Restrict for cross-schema
            .HasConstraintName($"fk__{BbuDb.SCHEMA}__{Asset.TABLE_NAME}__{SpatialDb.SCHEMA}__{Location.TABLE_NAME}__location_id");
    });
    

Error: Migration Already Applied

Error Messages:

Migration '20251029143022_AddUserEmail' has already been applied

Solutions:

  1. Check migration history:

    dplx db migrations list -c identity
    
  2. Remove and recreate if needed:

    # Remove last migration (if not applied to production!)
    dplx db migrations remove -c identity
    
    # Create new migration
    dplx db migrations add -c identity -n AddUserEmailRetry
    
  3. Skip if migration empty:

    # If you need to regenerate
    cd engines/identity/src/Acsis.Dynaplex.Engines.Identity.Database
    dotnet ef database update PreviousMigrationName
    dotnet ef migrations remove
    

Automatic Migration Troubleshooting

If you've enabled automatic migrations (ADR-036):

Problem: Auto-migrations not being generated

Check:

# Verify import is uncommented
grep "AutoMigration.targets" Directory.Build.props

# Should NOT see TODO comment before import
# Should see:
# <Import Project="$(StrataDir)resources/build/AutoMigration.targets" Condition="'$(IsDatabase)' == 'True'" />

Check if disabled:

# Environment variable check
echo $DISABLE_AUTO_MIGRATION  # Should be empty or false

# CI check
echo $CI  # Should be empty locally

Problem: Too many auto-migrations being created

Solution:

# Disable locally
export DISABLE_AUTO_MIGRATION=true

# Add to your shell profile (~/.bashrc or ~/.zshrc)
echo 'export DISABLE_AUTO_MIGRATION=true' >> ~/.zshrc

Problem: Auto-migration has wrong name

Solution: Auto-migrations always use timestamp format. If you need semantic names, use manual migrations:

# Disable auto-migration for this component
dotnet build engines/identity/src/Acsis.Dynaplex.Engines.Identity.Database/ /p:DISABLE_AUTO_MIGRATION=true

# Create named migration
dplx db migrations add -c identity -n AddUserEmailVerification

Using dplx CLI for Migrations

Check all pending migrations:

dplx db migrations pending

Check for CI (exits 1 if changes found):

dplx db migrations check

List migrations for a component:

dplx db migrations list -c identity

Add new migration:

dplx db migrations add -c identity -n DescribeYourChanges

Remove last migration:

dplx db migrations remove -c identity

Best Practices

  1. Always use dplx CLI - Ensures correct project references and naming
  2. Use .Database projects - Don't put migrations in .Abstractions
  3. Configure Passport FKs - Every entity needs explicit Passport FK configuration
  4. Use DateTime, not DateTimeOffset - PostgreSQL compatibility
  5. Descriptive migration names - Help future developers understand changes
  6. Review before committing - Check generated SQL in migration files
  7. Test migrations - Apply to local database before committing
  8. One logical change per migration - Easier to review and rollback if needed

🔄 Development Workflow Issues

Problem: IDE Not Recognizing Projects

Solutions:

  1. Reload solution:

    # Close and reopen development.slnx
    # Or in Visual Studio: File → Reload Solution
    
  2. Clear IDE cache:

    # Visual Studio
    rm -rf .vs/
    
    # Rider
    rm -rf .idea/
    
  3. Verify .slnx format:

    # Check file is valid XML
    cat acsis-core.slnx | head -20
    

Problem: Hot Reload Not Working

Solutions:

  1. Enable hot reload:

    dotnet watch run --project projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/
    
  2. Check file watchers:

    # Increase file watcher limit (Linux/Mac)
    echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
    sudo sysctl -p
    

📊 Performance Issues

Problem: Slow Application Startup

Diagnosis:

# Measure startup time
time dotnet run --project projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/

Solutions:

  1. Optimize component loading:

    // Load only required components
    services.LoadComponents(
        typeof(ICoreDataApi),
        typeof(IIdentityApi)
        // Remove unused components
    );
    
  2. Enable ready-to-run:

    <PropertyGroup>
      <PublishReadyToRun>true</PublishReadyToRun>
    </PropertyGroup>
    
  3. Check for blocking operations:

    // Avoid blocking async calls in startup
    // ❌ Bad
    await SomeAsyncOperation().ConfigureAwait(false);
    
    // ✅ Good - defer to background service
    services.AddHostedService<StartupBackgroundService>();
    

🆘 Getting Help

Diagnostic Information to Collect

When reporting issues, include:

  1. Environment Info:

    dotnet --info
    node --version  # If UI related
    git log -1 --oneline
    
  2. Build Output:

    dotnet build acsis-core.slnx --verbosity normal > build.log 2>&1
    
  3. Component Status:

    ls -la bin/components/
    
  4. Application Logs:

    dotnet run --project projects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/ > app.log 2>&1
    

Log Analysis

Enable Detailed Logging:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Acsis.Dynaplex.Projects.BbuRfid.ComponentLoader": "Debug",
      "Microsoft.EntityFrameworkCore": "Information"
    }
  }
}

Key Log Messages to Look For:

  • Component loading: Registering IMyComponentApi
  • Component registration: Registered MyComponentApi for IMyComponentApi
  • Assembly loading: Loading assembly from path
  • Database connections: Opening connection
  • HTTP requests: Executing endpoint

Common Log Patterns

Successful Component Loading:

info: Acsis.Dynaplex.Projects.BbuRfid.ComponentLoader[0] Registering ICoreDataApi
info: Acsis.Dynaplex.Projects.BbuRfid.ComponentLoader[0] Looking for implementation of ICoreDataApi
info: Acsis.Dynaplex.Projects.BbuRfid.ComponentLoader[0] Looking in Acsis.Dynaplex.Engines.CoreData
info: Acsis.Dynaplex.Projects.BbuRfid.ComponentLoader[0] Registered CoreDataApi for ICoreDataApi

Failed Component Loading:

info: Acsis.Dynaplex.Projects.BbuRfid.ComponentLoader[0] Registering IMyComponentApi
info: Acsis.Dynaplex.Projects.BbuRfid.ComponentLoader[0] Looking for implementation of IMyComponentApi
warn: Acsis.Dynaplex.Projects.BbuRfid.ComponentLoader[0] Warning: No implementation found for IMyComponentApi

Community Resources

Remember: Most issues are caused by component loading problems, build configuration issues, or missing dependencies. Start with the quick diagnosis steps and work through the specific problem areas systematically.