Graph is linked to private object(s) in an external package

Here is the full text of the error:

Can’t save …/…/…/…/…/…/Unreal Projects/UnrealStickFigure2D 4.10/Content/Maps/TrainingMap_1.umap: Graph is linked to private object(s) in an external package.
External Object(s):
AssetImportData

then…

The asset ‘/Game/Maps/TrainingMap_1’ (TrainingMap_1.umap) cannot be saved as the package is locked because you are in play on PC mode.

Cancel: Stop saving all assets and return to the editor.
Retry: Attempt to save the asset again.
Continue: Skip saving this asset only.

Now the scenario. I have a BP demo project, UnrealStickFigure2D. I decided to add C++ Pawn class to it. The pawn class has a few UPROPERTIES:

UPROPERTY(EditAnywhere, Category = Custom)
UPaperFlipbook * FlipBook;

UPROPERTY(EditAnywhere, Category = Custom)
UStaticMesh * StaticMesh;

UPROPERTY(EditAnywhere, Category = Custom)
UStaticMeshComponent * StaticMeshComponent;

In my constructor, the code below is the culprit, when I comment this out, I can save the project. If I leave this code in, I get the error above:

StaticMesh = CreateDefaultSubobject<UStaticMesh>("mesh");

USceneComponent * dummyRoot = CreateDefaultSubobject<USceneComponent>("dummy");

StaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>("StaticMesh");

StaticMeshComponent->AttachTo(dummyRoot);
RootComponent = dummyRoot;
StaticMeshComponent->SetStaticMesh(StaticMesh);

My question is, why is this code making it so I can’t save. I can’t run it either.

Hello omoplata,

This error message is usually the result in some bad references being made and can be fixed by cleaning up said references. From the code you’ve provided, the only thing that looks a bit odd is line #7 & 8. I’m not 100% sure if this would be the reference that is causing the problem but I would suggest removing line #7 as the StaticMeshComponent will be attached to the RootComponent automatically once it is set unless you attach it to something else manually.

If that doesn’t change anything, could you provide the rest of your code or at least the structure of your blueprints?

We haven’t heard from you in a while, omoplata. Are you still having issues saving your content? If so, have you tried looking into what I mentioned in my previous comment? Can you provide the information I requested as well? In the meantime, I’ll be marking this as resolved for tracking purposes.

yes, sorry, I was out of town for a while.

To give more info, my pawn class is nearly boilerplate. I’ve isolated the one line that is causing the issue:

StaticMesh = CreateDefaultSubobject<UStaticMesh>("mesh");

When I comment this line out, no error. When I keep it, I get the error.

The cpp file is practically empty, except the autogenerated boilerplate code for the APawn base class. The .h file with properties listed are the only other changes.

I can’t tell you much about the blueprint structure because…well, I don’t understand it. Its the unreal stick figure demo and the only thing I’ve added was my c++ pawn class to it. And on that c++ class, as of now, all I’m doing is creating the UStaticMesh and assigning it to the StaticMesh property. It seems that doing this in c++ causes problems. When I assign a static mesh from the Editor UI, there’s no problem.

Ok so more details. I tried adding the offending line of code above to an empty c++ starter content project - that one with the table and 2 chairs. I’m getting the same error, nothing to do with blueprints.

So clearly, that line is erroneous somehow. Can somebody explain to me why? Is the string “mesh” an issue? Does that need to refer to an actual existing mesh somewhere? I thought it was just some random string name to give an ID to the mesh?

I found it! Duh, the string is the name of an existing mesh. So “mesh” didn’t actually exist because I misunderstood (in hindsight how did I misunderstand that) what the string parameter of CreateDefaultSubobject() was. That string needs to refer to an existing asset in the project. Otherwise, the error makes sense now. It thinks that my asset exists somewhere else, but the fact is, its really saying it doesn’t know where to find the asset name I specified.

That being said, while my error, I think the error message was extremely vague.
I think at least an error message referring to the property I’m assigning to and the asset name would be much better to help locate the cause of the error. Luckily, my project was pretty much new, but imagine if the project were large, with hundreds or even thousands of programmaticallly assigned assets. It would be a nightmare to track down the offending line of code.

The Editor error is equivalent to a c++ compiler saying: “Syntax error: somewhere in your code”. I understand the Editor doesn’t know about c++ or line numbers, but it certainly knows about properties and the asset name being assigned. Couldn’t it be more specific?

I got this error while working on Blueprints.
I observed sometimes for unreal its difficult to save the information by directly referencing to that object. So I saved the class variable in blueprints, not object variable. And through that I instance a object in real time and then process that object. This trick worked! may be if you take it theoretically, this should solve your issue as well.

Hello omoplata,

Generally when I use CreateDefaultSubobject, I end up writing it like so:

MyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyMesh"));

Where the string parameter matches the name of the variable. It’s mainly by habit but I haven’t seen any issues of doing otherwise and putting different names there. Could you give some precise repro steps, even including the code itself if possible, to reproduce this save problem in a fresh project?

Using UE4.10.4

Note: The problem is caused by UStaticMesh, not UStaticMeshComponent. UStaticMeshComponent can have any string in the subobject creator.

  1. Create a new C++ pawn class.
  2. Add the following to your pawn.h file:
    UPROPERTY(EditAnywhere, Category = “Custom”)
    UStaticMesh * staticmesh;
  3. in your pawn.cpp: staticmesh = CreateDefaultSubobject(“randomstring3498udfgi”);
  4. drag your pawn into your level in the Editor
  5. hit the ‘Compile’ button

Ah I see now. Unfortunately the error message most likely won’t be any more precise than this, but it is already pointing toward the correct problem. The engine attempts to import the asset’s data for use but can’t find any asset that matches that and fails due to this. This works fine for the component instead as you’re only creating an instance of the component, not trying to assign an existing mesh. If you plan to be setting this Static Mesh elsewhere you should be able to skip assigning a default, as long as you’re sure to make checks for null whenever trying to refer to it.

As this seems to be resolved, I’ll be changing once of your previous comments to an answer and accepting it. If I’m wrong, please let me know and we can continue discussing.

Yes, I think its resolved. My complaint is that the error message, while it not as precise as I would like, doesn’t tell me which property is the offender.

So imagine if I had 100 different properties and 1 of them mistakenly pointed to a misspelled asset name/path. How would I identify which property is causing the problem?

As I mentioned, imagine if a c++ compiler gave a compiler error message, but no line number to indicate roughly the location of the error.

I just realized that CreateDefaultSubobject most likely wouldn’t be the best idea to use with a UStaticMesh pointer. ConstructorHelpers would be a better fit for this usage. The syntax I’m using is as follows, for a mesh object called “Cube” in my root content folder.

In .h

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyMesh")
	UStaticMesh* MyMesh;

In constructor:

ConstructorHelpers::FObjectFinder<UStaticMesh> Mesh(TEXT("/Game/Cube.Cube"));
	MyMesh = Mesh.Object;

I got the path by right-clicking the mesh and hitting “Copy Reference”. If this ends up being mispelled, you’ll get the following message in your output log, and best of all, it won’t stop you from saving your level:

Error: CDO Constructor (NewBlueprint_C): Failed to find /Game/Cube.Cub

As for the error message for CreateDefaultSubobject, I can enter a feature request if you wish but I also wouldn’t suggest creating many properties/variables at once without compiling/saving due to multiple errors appearing or crashes.

Thank you for the suggestion to use ConstructorHelpers.

I know we’re getting really offtopic here, but how do I know which methodology I should use to construct? Is ConstructorHelpers used specifically in instances where an existing asset is to be loaded as part of object creation?

And yes, I think it would be nice to have a feature that gives some hint as to which UPROPERTY/property was the offending error.

You’re correct, ConstructorHelpers is something that would be used whenever you wish to initialize a property with a default that exists in the content browser. CreateDefaultSubobject is for initializing a pointer with a new blank instance of that class.

I’ve placed a feature request in for the error message. For reference, the number is UE-28717. I’ll be sure to let you know if there are any updates or changes to the request.