Repository: ErikEJ/EFCorePowerTools (2026-04-17T05:44:04Z)

Issue:
Supports PostgreSQL's `citext` type in function
### What problem are you trying to solve?

I have a minimal reproduction repo for this problem: [ChrisTorng/PostgreSqlCitext/BeforeFix](https://github.com/ChrisTorng/PostgreSqlCitext/tree/main/BeforeFix).

---

I'm using 4/6/2026 2.6.1465 version of [EF Core Power Tools](https://marketplace.visualstudio.com/items?itemName=ErikEJ.EFCorePowerTools) to do Reverse Engineering.

There are four problems I'm facing:

1. For function with `citext` parameter, EFCPT can't generate codes.
2. For function with `citext` return value, EFCPT can't generate codes, with different error.
3. The generation stops without other normal ones generated, and not showing which item causes the problem.
4. The renaming of function returned table column doesn't work on Edit UI or on `efpt.renaming.json`.

This Feature Request focuses on problem 1/2/3.

### Problem 1: `citext` parameter in function

For a simple [`sql/testcitextin.sql`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/master/sql/testcitextin.sql), using original EF Core Power Tools to refresh [`BeforeFix/efpt.testcitextin.config.json`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/master/BeforeFix/efpt.testcitextin.config.json), it ends up this error message:
```
System.Exception: System.ArgumentOutOfRangeException: cleanedTypeName: USER-DEFINED (Parameter 'storeType')
   at RevEng.Core.Routines.Extensions.PostgresNpgsqlTypeExtensions.GetNpgsqlDbType(String storeType) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Extensions\PostgresNpgsqlTypeExtensions.cs:line 192
   at RevEng.Core.Routines.Extensions.PostgresNpgsqlTypeExtensions.GetClrType(String storeType, Boolean isNullable, String objectName, Boolean asParameter) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Extensions\PostgresNpgsqlTypeExtensions.cs:line 101
   at RevEng.Core.Routines.Extensions.PostgresNpgsqlTypeExtensions.ClrTypeFromNpgsqlParameter(ModuleParameter storedProcedureParameter, Boolean asMethodParameter) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Extensions\PostgresNpgsqlTypeExtensions.cs:line 82
   at RevEng.Core.Routines.Extensions.PostgresClrTypeMapper.GetClrType(ModuleParameter parameter) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Extensions\PostgresClrTypeMapper.cs:line 10
   at RevEng.Core.Routines.Procedures.ProcedureScaffolder.<>c__DisplayClass16_0.<CreateUsings>b__5(ModuleParameter p) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Procedures\ProcedureScaffolder.cs:line 197
   at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
   at RevEng.Core.Routines.Procedures.ProcedureScaffolder.CreateUsings(ModuleScaffolderOptions scaffolderOptions, RoutineModel model, List`1 schemas) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Procedures\ProcedureScaffolder.cs:line 197
   at RevEng.Core.Routines.Procedures.ProcedureScaffolder.WriteDbContextInterface(ModuleScaffolderOptions scaffolderOptions, RoutineModel model, List`1 schemas) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Procedures\ProcedureScaffolder.cs:line 226
   at RevEng.Core.Routines.Procedures.ProcedureScaffolder.ScaffoldModel(RoutineModel model, ModuleScaffolderOptions scaffolderOptions, List`1 schemas, List`1& errors) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Procedures\ProcedureScaffolder.cs:line 129
   at RevEng.Core.ReverseEngineerScaffolder.GenerateStoredProcedures(ReverseEngineerCommandOptions options, List`1 schemas, List`1& errors, String outputContextDir, String modelNamespace, String contextNamespace, Boolean supportsProcedures) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\ReverseEngineerScaffolder.cs:line 222
   at RevEng.Core.ReverseEngineerRunner.GenerateFiles(ReverseEngineerCommandOptions options) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\ReverseEngineerRunner.cs:line 107
```

### Problem 2: `citext` return value in function

For [`sql/testcitextout.sql`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/master/sql/testcitextout.sql) with [`BeforeFix/efpt.testcitextout.config.json`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/master/BeforeFix/efpt.testcitextout.config.json), it ends up this error message:
```
System.Exception: System.ArgumentOutOfRangeException: storetype: citext, objectName: testcitextout (Parameter 'storeType')
   at RevEng.Core.Routines.Extensions.PostgresNpgsqlTypeExtensions.GetClrType(String storeType, Boolean isNullable, String objectName, Boolean asParameter) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Extensions\PostgresNpgsqlTypeExtensions.cs:line 165
   at RevEng.Core.Routines.Extensions.PostgresNpgsqlTypeExtensions.GetClrType(ModuleResultElement moduleResultElement) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Extensions\PostgresNpgsqlTypeExtensions.cs:line 96
   at RevEng.Core.Routines.Extensions.PostgresClrTypeMapper.GetClrType(ModuleResultElement resultElement) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Extensions\PostgresClrTypeMapper.cs:line 15
   at RevEng.Core.Routines.Scaffolder.<WriteResultClass>b__4_0(ModuleResultElement p) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Scaffolder.cs:line 41
   at System.Collections.Generic.List`1.FindIndex(Int32 startIndex, Int32 count, Predicate`1 match)
   at System.Collections.Generic.List`1.Exists(Predicate`1 match)
   at RevEng.Core.Routines.Scaffolder.WriteResultClass(List`1 resultElements, ModuleScaffolderOptions options, String name, String schemaName) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Scaffolder.cs:line 41
   at RevEng.Core.Routines.Procedures.ProcedureScaffolder.ScaffoldModel(RoutineModel model, ModuleScaffolderOptions scaffolderOptions, List`1 schemas, List`1& errors) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Procedures\ProcedureScaffolder.cs:line 75
   at RevEng.Core.ReverseEngineerScaffolder.GenerateStoredProcedures(ReverseEngineerCommandOptions options, List`1 schemas, List`1& errors, String outputContextDir, String modelNamespace, String contextNamespace, Boolean supportsProcedures) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\ReverseEngineerScaffolder.cs:line 222
   at RevEng.Core.ReverseEngineerRunner.GenerateFiles(ReverseEngineerCommandOptions options) in D:\a\EFCorePowerTools\EFCorePowerTools\src\Core\RevEng.Core.80\ReverseEngineerRunner.cs:line 107
```

### Problem 3: Generate stops without showing which item causes the problem

For both cases, the generate stops, without anything like [`sql/testtext.sql`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/master/sql/testtext.sql) related generated. You can check [`BeforeFix/TestCitextInModels/`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/master/BeforeFix/TestCitextInModels/) and [`BeforeFix/TestCitextOutModels/`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/master/BeforeFix/TestCitextOutModels/) folders for generated codes.

For [`sql/testcitextin.sql`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/master/sql/testcitextin.sql) one, the error message doesn't shows which item causes this problem, makes it hard to find out the problematic item while there are lots of items.

But for [`sql/\testtext.sql`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/master/sql/testtext.sql) with [`BeforeFix/efpt.testtext.config.json`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/master/BeforeFix/efpt.testtext.config.json), it generates codes in [`BeforeFix/TestTextModels/`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/master/BeforeFix/TestTextModels/) successfully.

### Describe the solution you'd like

## The Fixes

I've forked [ErikEJ/EFCorePowerTools](https://github.com/ErikEJ/EFCorePowerTools) from [chore: move sln to slnx (#3343)](https://github.com/ErikEJ/EFCorePowerTools/commit/cfb4c2f99616d8e2886440d35555fa1b4c842457) into my repo [ChrisTorng/EFCorePowerTools](https://github.com/ChrisTorng/EFCorePowerTools). With the help of GitHub Copilot, I made some changes to make it works on my Visual Studio 2026 Insiders, easier to debug (cause I can't found other easier ways). And the fixes are these:

1. Problem 1/2 (`citext` in/out): [Fix citext in/out parameter code gen](https://github.com/ChrisTorng/EFCorePowerTools/commit/96a3ec6407b33766da612f1acba6aee945e8c5bf) and [Fix citext in/out parameter code genenation](https://github.com/ChrisTorng/EFCorePowerTools/commit/fde5123aa40cbf9a6144306502e725439da85015).
2. Problem 3 (generation stops without which): [Always generate code by pre-check, print error message and remove problematic items](https://github.com/ChrisTorng/EFCorePowerTools/commit/2ba803314e3b0adca9e5217777a1feec8ae1adda).

### The Results

The fixed version of EFCPT, Refreshing the [`AfterFix/efpt.config.json`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/master/AfterFix/efpt.config.json), has one error message left:
```
Unable to scaffold "dbo"."testrefcursor": parameter 'p_refcur' has unsupported store type 'refcursor'. storetype: refcursor, objectName: p_refcur (Parameter 'storeType')
```

It clearly indicates the problematic item, without blocking others. (We are not willing to use `refcursor`, so it's not a blocking problem for us.)

And all other codes generated successfully, under [`AfterFix/Models/`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/master/AfterFix/Models/) folders. Mainly in [`AfterFix/Models/TestTextResult.cs`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/master/AfterFix/Models/PGContextFunctions.cs) with `testcitextinAsync()`/`testcitextoutAsync()`/`TestTextAsync()` generated.

## No PR for original repo

Sorry it's hard for me to contribute a PR to the original repo, because of:

1. These changes are made by GitHub Copilot mainly. I can understand some easier ones. But I can't fully understand the whole picture of EFCPT.
2. I didn't drill down into how to unit test these changes, by EFCPT's own way.
3. I've changed many other files for local running/debugging. I believe these are not what you want.
4. I'm not familiar of how GitHub/PR works.

Hope these fixes helps EFCPT to support PostgreSQL `citext` type, and easier to diagnose problems.


Discussion:
@ChrisTorng  Thanks, I will try to get this into the main codebase
fixed in https://github.com/ChrisTorng/EFCorePowerTools/commit/96a3ec6407b33766da612f1acba6aee945e8c5bf and https://github.com/ChrisTorng/EFCorePowerTools/commit/fde5123aa40cbf9a6144306502e725439da85015 
@ChrisTorng I implemented a fix for this in the [latest daily build](https://www.vsixgallery.com/extension/f4c4712c-ceae-4803-8e52-0e2049d5de9f), would be grateful if you could try it out.

If you like my free tools, I would be very grateful for a rating/review on [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ErikEJ.EFCorePowerTools&ssr=false#review-details) and/or a [one-time or monthly sponsorship](https://github.com/sponsors/ErikEJ?frequency=one-time&sponsor=ErikEJ)
Thanks for your kindly help. I have tried 2.6.1584, but the result is still the same, with different build path. I have update my [ChrisTorng/PostgreSqlCitext](https://github.com/ChrisTorng/PostgreSqlCitext) repo with [Official_2_6_1584](https://github.com/ChrisTorng/PostgreSqlCitext/tree/main/Official_2_6_1584) result.

### Problem 1: `citext` parameter in function

For [`Official_2_6_1584/efpt.testcitextin.config.json`](Official_2_6_1584/efpt.testcitextin.config.json):

```
System.Exception: System.ArgumentOutOfRangeException: cleanedTypeName: USER-DEFINED (Parameter 'storeType')
   at RevEng.Core.Routines.Extensions.PostgresNpgsqlTypeExtensions.GetNpgsqlDbType(String storeType) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Extensions\PostgresNpgsqlTypeExtensions.cs:line 192
   at RevEng.Core.Routines.Extensions.PostgresNpgsqlTypeExtensions.GetClrType(String storeType, Boolean isNullable, String objectName, Boolean asParameter) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Extensions\PostgresNpgsqlTypeExtensions.cs:line 101
   at RevEng.Core.Routines.Extensions.PostgresNpgsqlTypeExtensions.ClrTypeFromNpgsqlParameter(ModuleParameter storedProcedureParameter, Boolean asMethodParameter) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Extensions\PostgresNpgsqlTypeExtensions.cs:line 82
   at RevEng.Core.Routines.Extensions.PostgresClrTypeMapper.GetClrType(ModuleParameter parameter) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Extensions\PostgresClrTypeMapper.cs:line 10
   at RevEng.Core.Routines.Procedures.ProcedureScaffolder.<>c__DisplayClass16_0.<CreateUsings>b__4(ModuleParameter p) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Procedures\ProcedureScaffolder.cs:line 160
   at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
   at RevEng.Core.Routines.Procedures.ProcedureScaffolder.CreateUsings(ModuleScaffolderOptions scaffolderOptions, RoutineModel model, List`1 schemas) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Procedures\ProcedureScaffolder.cs:line 160
   at RevEng.Core.Routines.Procedures.ProcedureScaffolder.WriteDbContextInterface(ModuleScaffolderOptions scaffolderOptions, RoutineModel model, List`1 schemas) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Procedures\ProcedureScaffolder.cs:line 184
   at RevEng.Core.Routines.Procedures.ProcedureScaffolder.ScaffoldModel(RoutineModel model, ModuleScaffolderOptions scaffolderOptions, List`1 schemas, List`1& errors) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Procedures\ProcedureScaffolder.cs:line 97
   at RevEng.Core.ReverseEngineerScaffolder.GenerateStoredProcedures(ReverseEngineerCommandOptions options, List`1 schemas, List`1& errors, String outputContextDir, String modelNamespace, String contextNamespace, Boolean supportsProcedures) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\ReverseEngineerScaffolder.cs:line 221
   at RevEng.Core.ReverseEngineerRunner.GenerateFiles(ReverseEngineerCommandOptions options) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\ReverseEngineerRunner.cs:line 107
```

It only generate a single file: [`Official_2_6_1584/TestCitextInModels/PGContext.cs`](Official_2_6_1584/TestCitextInModels/PGContext.cs).

### Problem 2: `citext` return value in function

For [`Official_2_6_1584/efpt.testcitextout.config.json`](Official_2_6_1584/efpt.testcitextout.config.json):

```
System.Exception: System.ArgumentOutOfRangeException: storetype: citext, objectName: testcitextout (Parameter 'storeType')
   at RevEng.Core.Routines.Extensions.PostgresNpgsqlTypeExtensions.GetClrType(String storeType, Boolean isNullable, String objectName, Boolean asParameter) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Extensions\PostgresNpgsqlTypeExtensions.cs:line 165
   at RevEng.Core.Routines.Extensions.PostgresNpgsqlTypeExtensions.GetClrType(ModuleResultElement moduleResultElement) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Extensions\PostgresNpgsqlTypeExtensions.cs:line 96
   at RevEng.Core.Routines.Extensions.PostgresClrTypeMapper.GetClrType(ModuleResultElement resultElement) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Extensions\PostgresClrTypeMapper.cs:line 15
   at RevEng.Core.Routines.Scaffolder.<WriteResultClass>b__4_0(ModuleResultElement p) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Scaffolder.cs:line 41
   at System.Collections.Generic.List`1.FindIndex(Int32 startIndex, Int32 count, Predicate`1 match)
   at System.Collections.Generic.List`1.Exists(Predicate`1 match)
   at RevEng.Core.Routines.Scaffolder.WriteResultClass(List`1 resultElements, ModuleScaffolderOptions options, String name, String schemaName) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Scaffolder.cs:line 41
   at RevEng.Core.Routines.Procedures.ProcedureScaffolder.ScaffoldModel(RoutineModel model, ModuleScaffolderOptions scaffolderOptions, List`1 schemas, List`1& errors) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\Routines\Procedures\ProcedureScaffolder.cs:line 75
   at RevEng.Core.ReverseEngineerScaffolder.GenerateStoredProcedures(ReverseEngineerCommandOptions options, List`1 schemas, List`1& errors, String outputContextDir, String modelNamespace, String contextNamespace, Boolean supportsProcedures) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\ReverseEngineerScaffolder.cs:line 221
   at RevEng.Core.ReverseEngineerRunner.GenerateFiles(ReverseEngineerCommandOptions options) in C:\dev\GitHub\EFCorePowerTools\src\Core\RevEng.Core.80\ReverseEngineerRunner.cs:line 107
```

It only generate a single file: [`Official_2_6_1584/TestCitextOutModels/PGContext.cs`](Official_2_6_1584/TestCitextOutModels/PGContext.cs).
@ChrisTorng maybe get the latest master and ask your agent why it is not working? I have no easy way to verify

## Official_20260420

I found that the [latest daily build 2.6.1584](https://www.vsixgallery.com/extension/f4c4712c-ceae-4803-8e52-0e2049d5de9f)'s [`EF Core Power Tools v2.6.1584.vsix`](https://www.vsixgallery.com/extensions/f4c4712c-ceae-4803-8e52-0e2049d5de9f/EF%20Core%20Power%20Tools%20v2.6.1584.vsix), has an old `efreveng80.exe.zip` inside. The latest file in `efreveng80.exe.zip` is 2025/9/26, not the expected 2026/4/17.

I've forked [ErikEJ/EFCorePowerTools](https://github.com/ErikEJ/EFCorePowerTools) from 2026/4/17 [Enable SQLite NodaTime support in EF Core 10 scaffolding paths (#3417)](https://github.com/ErikEJ/EFCorePowerTools/commit/178238bed4aa3cc5092ee28f28e6f7cdca239147) into my repo [ChrisTorng/EFCorePowerTools](https://github.com/ChrisTorng/EFCorePowerTools)'s [upstream_20260420](https://github.com/ChrisTorng/EFCorePowerTools/tree/upstream_20260420) branch.

After fix build problems:

1. Run `RevEng\efreveng80\BuildCmdlineTool.cmd` to generate `EFCorePowerTools\efreveng80.exe.zip`.
2. Delete `%TEMP%\efreveng8.2.6.0.1` folder.
3. Run `EFCorePowerTools`, it will recreate `%TEMP%\efreveng8.2.6.0.1` folder by unzipping `EFCorePowerTools\efreveng80.exe.zip` into it.

The results:
1. For [`Official_20260420/efpt.testcitextin.config.json`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/main/Official_20260420/efpt.testcitextin.config.json): it generates [`Official_20260420/TestCitextInModels`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/main/Official_2_6_1584/TestCitextInModels) successfully without error message.
2. For [`Official_20260420/efpt.testcitextout.config.json`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/main/Official_20260420/efpt.testcitextout.config.json): it generates [`Official_20260420/TestCitextOutModels`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/main/Official_2_6_1584/TestCitextOutModels) successfully without error message.  

But the code under [`Official_20260420/TestCitextOutModels`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/main/Official_2_6_1584/TestCitextOutModels) has errors:

[`Official_20260420/IPGContextFunctions.cs`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/main/Official_20260420/TestCitextOutModels/IPGContextFunctions.cs) L16 lacks first parameter:
```
Task<List<testcitextoutResult>> testcitextoutAsync(, CancellationToken cancellationToken = default);
```

[`Official_20260420/PGContextFunctions.cs`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/main/Official_20260420/TestCitextOutModels/PGContextFunctions.cs) L46-54 lacks first parameter, and `npgsqlParameters` has [CS0826](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/array-declaration-errors#invalid-element-type): `No best type found for implicitly-typed array` error:
```
public virtual async Task<List<testcitextoutResult>> testcitextoutAsync(, CancellationToken ancellationToken = default)
{
    var npgsqlParameters = new []
    {
    };
    var _ = await _context.SqlQueryAsync<testcitextoutResult>("SELECT * FROM \"dbo\"."testcitextout\" ()", npgsqlParameters, cancellationToken);

    return _;
}
```
## Official_20260420_Fix

In [Fix code generation without input parameter's case](https://github.com/ErikEJ/EFCorePowerTools/commit/c22fe2dcae1434637fd8257573d47be630761507) commit, after reapply fixes in [Fix citext in/out parameter code gen.](https://github.com/ErikEJ/EFCorePowerTools/commit/96a3ec6407b33766da612f1acba6aee945e8c5bf)'s [`RevEng.Core.80\Routines\PostgresRoutineModelFactory.cs](https://github.com/ErikEJ/EFCorePowerTools/commit/96a3ec6407b33766da612f1acba6aee945e8c5bf#diff-ac24f86d23f7321881c82ba1308e5656e795749d8ccbb903f4c6ce9332cc8cbf):
```
Sb.AppendLine("var npgsqlParameters = new []");
```
↓
```
Sb.AppendLine("var npgsqlParameters = new object[]");
```

```
line += useAsyncCalls ? $", CancellationToken{nullable} cancellationToken = default)" : ")";
```
↓
```
var hasParams = paramStrings.Any() || outParams.Count > 0;
line += useAsyncCalls
    ? $"{(hasParams ? ", " : string.Empty)}CancellationToken{nullable} cancellationToken = default)"
    : ")";
```

It generates [`Official_20260420_Fix/IPGContextFunctions.cs`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/main/Official_20260420_Fix/TestCitextOutModels/IPGContextFunctions.cs)/[`Official_20260420_Fix/PGContextFunctions.cs`](https://github.com/ChrisTorng/PostgreSqlCitext/blob/main/Official_20260420_Fix/TestCitextOutModels/PGContextFunctions.cs) succesfully without error message. The code is correct too.
@ChrisTorng You are looking at latest master barnch, not the produced vsix:

<img width="702" height="108" alt="Image" src="https://github.com/user-attachments/assets/e939d3d5-11c1-463d-9276-c5216a845cbd" />
I had triple confirmed that:

Inside `EF Core Power Tools v2.6.1584.vsix`, the `efreveng80.exe.zip`'s `Date modified` is 4/17/2026:
<img width="1456" height="789" alt="Image" src="https://github.com/user-attachments/assets/7b9a28c6-0d7e-4fde-a026-6387932723d3" />

And inside the `efreveng80.exe.zip`, the `efreveng80.dll`'s `Date modified` is 9/26/2025:
<img width="1761" height="756" alt="Image" src="https://github.com/user-attachments/assets/8fa92644-c6ae-491f-bf59-d35f3a8dd2a9" />

And as I checked the master branch before, the code generated has a bug that doesn't compile while there is no input parameter.
> the code generated has a bug that doesn't compile while there is no input parameter.

@ChrisTorng So there is a bug in the current master? Do you have a fix for that?
@ChrisTorng Ah. looks like the .1584 build was broken! I will fix and you should get a newer working build soon
> > the code generated has a bug that doesn't compile while there is no input parameter.
> [@ChrisTorng](https://github.com/ChrisTorng) So there is a bug in the current master? Do you have a fix for that?

I had stated the problem in [Official_20260420](https://github.com/ErikEJ/EFCorePowerTools/issues/3402#issuecomment-4286199902) and my solution in [Official_20260420_Fix](https://github.com/ErikEJ/EFCorePowerTools/issues/3402#issuecomment-4286214723) comments. Are there anything needs me to clarify?
@ChrisTorng Got it, thanks! 
I implemented a fix for this in the [latest daily build](https://www.vsixgallery.com/extension/f4c4712c-ceae-4803-8e52-0e2049d5de9f), would be grateful if you could try it out.
It passed all my tests. Thanks for adding this feature.
@ChrisTorng Thanks for your contribution! I will look into the renaming issue "soon"



Patch:
diff --git a/src/Core/RevEng.Core.80/Routines/Extensions/PostgresNpgsqlTypeExtensions.cs b/src/Core/RevEng.Core.80/Routines/Extensions/PostgresNpgsqlTypeExtensions.cs
index 98c7d741e..12c1e84ed 100644
--- a/src/Core/RevEng.Core.80/Routines/Extensions/PostgresNpgsqlTypeExtensions.cs
+++ b/src/Core/RevEng.Core.80/Routines/Extensions/PostgresNpgsqlTypeExtensions.cs
@@ -120,6 +120,7 @@ public static Type GetClrType(string storeType, bool isNullable, string objectNa
                 case NpgsqlDbType.Jsonb:
                 case NpgsqlDbType.Xml:
                 case NpgsqlDbType.TsQuery:
+                case NpgsqlDbType.Citext:
                     return typeof(string);
 
                 case NpgsqlDbType.Date:
@@ -233,4 +234,4 @@ private static string RemoveMatchingBraces(string s)
             return string.Join(string.Empty, stack.Reverse());
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/Core/RevEng.Core.80/Routines/PostgresRoutineModelFactory.cs b/src/Core/RevEng.Core.80/Routines/PostgresRoutineModelFactory.cs
index df653de59..e9b774f60 100644
--- a/src/Core/RevEng.Core.80/Routines/PostgresRoutineModelFactory.cs
+++ b/src/Core/RevEng.Core.80/Routines/PostgresRoutineModelFactory.cs
@@ -133,6 +133,7 @@ private static Dictionary<string, List<ModuleParameter>> GetParameters(NpgsqlCon
        args.parameter_name,
        args.parameter_mode,
        args.data_type,
+       args.udt_name,
 	   args.character_maximum_length,
 	   args.numeric_precision,
 	   args.numeric_scale
@@ -158,15 +159,23 @@ where proc.routine_schema not in ('pg_catalog', 'information_schema')
             {
                 if (par != null)
                 {
+                    if (par["parameter_mode"] is DBNull)
+                    {
+                        continue;
+                    }
+
+                    var dataType = par["data_type"].ToString();
                     var parameter = new ModuleParameter()
                     {
                         Name = par["parameter_name"].ToString(),
                         RoutineName = par["procedure_name"].ToString(),
                         RoutineSchema = par["procedure_schema"].ToString(),
-                        StoreType = par["data_type"].ToString(),
+                        StoreType = dataType == "USER-DEFINED"
+                            ? par["udt_name"].ToString()
+                            : dataType,
                         Length = (par["character_maximum_length"] is DBNull) ? (int?)null : int.Parse(par["character_maximum_length"].ToString()!, CultureInfo.InvariantCulture),
-                        Precision = (par["numeric_precision"] is DBNull) ? (int?)null : int.Parse(par["Precision"].ToString()!, CultureInfo.InvariantCulture),
-                        Scale = (par["numeric_scale"] is DBNull) ? (int?)null : int.Parse(par["Scale"].ToString()!, CultureInfo.InvariantCulture),
+                        Precision = (par["numeric_precision"] is DBNull) ? (int?)null : int.Parse(par["numeric_precision"].ToString()!, CultureInfo.InvariantCulture),
+                        Scale = (par["numeric_scale"] is DBNull) ? (int?)null : int.Parse(par["numeric_scale"].ToString()!, CultureInfo.InvariantCulture),
                         Output = par["parameter_mode"].ToString() == "INOUT",
                         Nullable = true,
                     };
@@ -181,4 +190,4 @@ where proc.routine_schema not in ('pg_catalog', 'information_schema')
             return result.GroupBy(x => $"{x.RoutineSchema}.{x.RoutineName}").ToDictionary(g => g.Key, g => g.ToList(), StringComparer.InvariantCulture);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/Core/RevEng.Core.80/Routines/Procedures/PostgresStoredProcedureModelFactory.cs b/src/Core/RevEng.Core.80/Routines/Procedures/PostgresStoredProcedureModelFactory.cs
index 959dfaad2..60051aaf3 100644
--- a/src/Core/RevEng.Core.80/Routines/Procedures/PostgresStoredProcedureModelFactory.cs
+++ b/src/Core/RevEng.Core.80/Routines/Procedures/PostgresStoredProcedureModelFactory.cs
@@ -198,7 +198,7 @@ from cte1
                     {
                         var name = names[i];
 
-                        if (name.StartsWith('"') && name.EndsWith('"'))
+                        if (name.Length >= 2 && name.StartsWith('"') && name.EndsWith('"'))
                         {
                             name = name.Substring(1, name.Length - 2);
                         }
@@ -212,6 +212,32 @@ from cte1
                         });
                     }
                 }
+                else
+                {
+                    var returnType = row["return_type"].ToString();
+                    if (!string.IsNullOrEmpty(returnType) && returnType != "void")
+                    {
+                        var names = (string[])row["return_record_names"];
+                        var types = (string[])row["return_record_types"];
+                        for (var i = 0; i < names.Length; i++)
+                        {
+                            var name = names[i];
+
+                            if (name.Length >= 2 && name.StartsWith('"') && name.EndsWith('"'))
+                            {
+                                name = name.Substring(1, name.Length - 2);
+                            }
+
+                            list.Add(new ModuleResultElement
+                            {
+                                Name = name,
+                                StoreType = types[i],
+                                Ordinal = i,
+                                Nullable = true,
+                            });
+                        }
+                    }
+                }
             }
 
             var result = new List<List<ModuleResultElement>>
@@ -222,4 +248,4 @@ from cte1
             return result;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/Core/RevEng.Core.80/Routines/Procedures/ProcedureScaffolder.cs b/src/Core/RevEng.Core.80/Routines/Procedures/ProcedureScaffolder.cs
index 0d917f42b..a2db34fc2 100644
--- a/src/Core/RevEng.Core.80/Routines/Procedures/ProcedureScaffolder.cs
+++ b/src/Core/RevEng.Core.80/Routines/Procedures/ProcedureScaffolder.cs
@@ -53,6 +53,45 @@ public ScaffoldedModel ScaffoldModel(RoutineModel model, ModuleScaffolderOptions
 
             schemas = schemas ?? new List<string>();
 
+            var invalidRoutines = new HashSet<Routine>();
+            foreach (var routine in model.Routines)
+            {
+                foreach (var parameter in routine.Parameters)
+                {
+                    try
+                    {
+                        typeMapper.GetClrType(parameter);
+                    }
+                    catch (ArgumentException ex)
+                    {
+                        errors.Add($"Unable to scaffold \"{routine.Schema}\".\"{routine.Name}\": parameter '{parameter.Name}' has unsupported store type '{parameter.StoreType}'. {ex.Message}");
+                        invalidRoutines.Add(routine);
+                        break;
+                    }
+                }
+
+                if (invalidRoutines.Contains(routine))
+                {
+                    continue;
+                }
+
+                foreach (var resultElement in routine.Results.SelectMany(r => r))
+                {
+                    try
+                    {
+                        typeMapper.GetClrType(resultElement);
+                    }
+                    catch (ArgumentException ex)
+                    {
+                        errors.Add($"Unable to scaffold \"{routine.Schema}\".\"{routine.Name}\": result column '{resultElement.Name}' has unsupported store type '{resultElement.StoreType}'. {ex.Message}");
+                        invalidRoutines.Add(routine);
+                        break;
+                    }
+                }
+            }
+
+            model.Routines.RemoveAll(r => invalidRoutines.Contains(r));
+
             foreach (var routine in model.Routines.Where(r => string.IsNullOrEmpty(r.MappedType) && (!(r is Function f) || !f.IsScalar)))
             {
                 var i = 1;
@@ -484,4 +523,4 @@ private void GenerateToDataTableExtension()
             }
         }
     }
-}
\ No newline at end of file
+}


Test patch:
diff --git a/src/Core/NUnitTestCore/PostgresTypeExtensionsTest.cs b/src/Core/NUnitTestCore/PostgresTypeExtensionsTest.cs
new file mode 100644
index 000000000..ca2930145
--- /dev/null
+++ b/src/Core/NUnitTestCore/PostgresTypeExtensionsTest.cs
@@ -0,0 +1,19 @@
+using System;
+using RevEng.Core.Routines.Extensions;
+using Xunit;
+
+namespace UnitTests
+{
+    public class PostgresTypeExtensionsTest
+    {
+        [Theory]
+        [InlineData(true)]
+        [InlineData(false)]
+        public void CanMapCitextToString(bool isNullable)
+        {
+            var result = PostgresNpgsqlTypeExtensions.GetClrType("citext", isNullable, "test");
+
+            Assert.Equal(typeof(string), result);
+        }
+    }
+}