Importing world deletes most actors in actors tab

This has happened since I updated my Foundry (on Forge) to the latest version. Launching my world tonight deleted most (90%) of the actors I had in my actors tab. Thankfully, I had all of them on my original Foundry page, but this was disheartening. The worst part, this continues to happen each time I import and launch the world in Forge. Is there any way to stop this? How do I go back to an older version? Could it be my modules? I’d really like a solution since this messed up my game with my players tonight and could continue to mess stuff up in the future.

Heya :wave:

Are you running dnd5e v2.1.x? That system recently introduced changes to model validation that can cause actors to be hidden after failing validation and migration.

I recommend launching your world in safe configuration (all modules disabled), and giving it enough time to finish migrating the world data to the new system version. You can track progress in the dev tools console (F12) or you’ll receive a notification message in Foundry once it’s done.

After that, run the included macro/script at the bottom of this post. This should fix model validation errors and refresh your game, letting you see the now-fixed actors again!

Let us know if it worked for you!

for (const id of game.actors.invalidDocumentIds) {
    const actor = game.actors.getInvalid(id);

    ui.notifications.info(`Fixing ${actor.name} (${actor.uuid})`);

    await actor.update(actor.toObject(), { diff: false })
}

for (const scene of game.scenes) {
    for (const token of scene.tokens) {
        if (!token.id) {
            continue;
        }

        const actorId = token.actorId;
        const baseActor = game.actors.get(actorId)
            ?? (game.actors.invalidDocumentIds.has(actorId)
                ? game.actors.getInvalid(actorId) : null);

        if (!baseActor) {
            continue;
        }

        const overrides = getDocumentClass("Actor").schema.clean(token.actorData, { partial: true });
        const actorData = foundry.utils.mergeObject(baseActor.toObject(), overrides);
        const actor = getDocumentClass("Actor").fromSource(foundry.utils.deepClone(actorData), { parent: token });
        const fixedActorData = foundry.utils.filterObject(actor.toObject(), token.actorData);
        const diffActorData = foundry.utils.diffObject(token.actorData, fixedActorData);

        if (foundry.utils.isEmpty(diffActorData)) {
            continue;
        }

        ui.notifications.info(`Fixing ${token.name} (${token.uuid})`);

        if (token.actorLink) {
            await token.update({ actorData: diffActorData }, { diff: false });
        } else {
            await token.update({ actorLink: true }, { diff: false });
            await token.update({ actorLink: false, actorData: diffActorData }, { diff: false });
        }
    }
}

foundry.utils.debouncedReload();

(Thanks to the folks over on the Foundry Discord for the script!)

I did this and have now gotten all of my characters back. Thank you very much!

1 Like