Quick answer: Commit .uid sidecar files. Use load("uid://...") for cross-rename-stable references. ResourceUID APIs convert paths to UIDs.

Designer renames enemy_grunt.tres to enemy_brute.tres. Half the scenes lose the reference. The ones that used UIDs are fine. The ones that used res:// paths broke.

The Symptom

After git pull or rename, you see ext_resource: Could not load type or scenes opening with placeholder broken references.

The Fix

# 1. Always commit .uid sidecars
.gitignore:
  # do NOT ignore *.uid
  # DO ignore .godot/ except imported.* if you want fresh imports

# 2. Reference by UID, not path
var grunt = load("uid://b8x2c4d9a1e3f")
# instead of load("res://enemies/grunt.tres")

# 3. Convert programmatically
var uid = ResourceUID.path_to_uid("res://enemies/grunt.tres")
var uid_str = ResourceUID.id_to_text(uid)
print(uid_str)  # "uid://b8x2c4d9a1e3f"

UID survives renames and moves. Unique per resource creation, persisted to .uid sidecar.

Recovering Broken Refs

If you renamed without sidecars, scenes will show broken-ext-resource. Re-link manually in editor; the new UID propagates to dependent scenes that re-open. Or run a search-replace across .tscn files swapping the old path.

Verifying

Rename a resource. Reload the project. Scenes still find it. Check .uid appears in git status as committed.

“UID, not path. Sidecar committed. Renames don’t break.”

Related Issues

For C# List property edits, see List property. For tween signal, see tween signal.

Commit the sidecar. UID stays. Refs hold.