UE 5.7 K2Node async : FString parameter in DECLARE_DYNAMIC_MULTICAST_DELEGATE does not generate output pin on the BP node

I have a UBlueprintAsyncActionBase-derived proxy class with two BlueprintAssignable multicast delegates :

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(

FMyCompletedDelegate,

const TArray<float>&, Output);

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(

FMyFailedDelegate,

const FString&, Reason);

UCLASS()

class MYMODULE_API UMyAsyncAction : public UBlueprintAsyncActionBase

{

GENERATED_BODY()

public:

UPROPERTY(BlueprintAssignable)

FMyCompletedDelegate OnCompleted;

UPROPERTY(BlueprintAssignable)

FMyFailedDelegate OnFailed;

UFUNCTION(BlueprintCallable, Category="MyCategory",

meta=(BlueprintInternalUseOnly="true",

WorldContext="WorldContextObject",

DisplayName="My Async Action"))

static UMyAsyncAction* MyAsyncAction(

UObject* WorldContextObject, ...);

virtual void Activate() override;

};

The generated K2Node in Blueprint shows :

  • On Completed exec pin + Output data pin (TArray) :white_check_mark:

  • On Failed exec pin WITHOUT any Reason data pin :cross_mark:

The OnFailed exec pin works (firing, broadcast received, downstream nodes execute), but the Reason parameter is invisible to BP.

What I have verified :

  1. UHT generates both delegate signature functions correctly :

    obj list class=Function name=FMyCompletedDelegate__DelegateSignature  -> 1 instance
    

    obj list class=Function name=FMyFailedDelegate__DelegateSignature -> 1 instance

  2. Only one instance of the proxy class loaded (no REINST_* or HOTRELOADED_* duplicates) :

    obj list class=Class name=MyAsyncAction  -> 1 instance
    
  3. The .gen.cpp registers OnFailed as BlueprintAssignable with identical flags to OnCompleted :

    NewProp_OnCompleted flags = 0x0010000010080000
    

    NewProp_OnFailed flags = 0x0010000010080000 (identical)

  4. The difference appears in the delegate signature property/function flags :

    FMyCompletedDelegate (TArray param) :
    

    NewProp_Output = 0x0010000008000182 (Parm | OutParm | RefParm | ConstParm | NativeAccessPublic)

    FuncParams = 0x00530000 (HasOutParms | Public | MulticastDelegate | Delegate)

    FMyFailedDelegate (FString param) :

    NewProp_Reason = 0x0010000000000080 (only Parm | NativeAccessPublic)

    FuncParams = 0x00130000 (no HasOutParms)

    UHT does not promote const FString& to a ref/out param in delegate signatures, while it does for TArray<T>&.

What I have already tried :

  • const FString& → no pin

  • FString (by value) → no pin

  • UPARAM(ref) const FString& → does not compile (UPARAM is not accepted inside DECLARE_DYNAMIC_MULTICAST_DELEGATE_* macros)

  • Manually patching the .gen.cpp to set 0x0010000008000182 on NewProp_Reason and 0x00530000 on FuncParams (matching the working TArray case), then rebuilding the .dll → still no pin

  • Renaming the UPROPERTY from OnError to OnFailed → no effect

  • Full clean rebuild (deleted Binaries/ and Intermediate/), full editor restart, fresh BP from scratch → still no pin

The manual flag patch is what I find most surprising : I confirmed via .dll timestamp + obj list that the patched binary was actually loaded, and the K2Node still does not generate the Reason pin even though the property and function flags are now byte-identical to the working Output/OnCompleted case.

The only difference left between the two cases is the property type itself : FArrayProperty (works) vs FStrProperty (does not work).

My questions :

  1. Is there a known UE 5.7 limitation or behavior in UK2Node_BaseAsyncTask::CreatePinsForClass (or downstream pin-generation logic) that filters out FStrProperty parameters from delegate signatures, even when they have the standard out/ref/const flags?

  2. If yes, is there a way to declare a BlueprintAssignable delegate with a FString parameter that does produce a BP pin, without wrapping it in a USTRUCT?

  3. If a USTRUCT wrapper is the only way, is this a known/documented limitation or just an empirical workaround the community has converged on?

Workaround I plan to apply : wrap the FString in a USTRUCT(BlueprintType). Confirming this is the right path before changing the API.

Engine version : UE 5.7

Yes, there is a limitation to async action blueprint nodes in the engine. They only support a single delegate signature. The output pins that you see will always be the ones from the first delegate property.

You can reorganize your delegates to only need one type.

Or…

If you have a source build, you can edit the engine. I had a pull request (here) that was declined that fixed this in one way. Or you could write your own blueprint node and use that for your async action.