affaan-m/ECC · error · RuntimeError
Resolve returned an item without an identity
Error message
Resolve returned an item without an identity
What it means
During readback, tasteforge identities each appended clip via GetUniqueId (falling back to id()). If Resolve returns an item whose identity is None, matching it against the placement's members is impossible, so this RuntimeError is raised as an internal invariant violation.
Solutions
- Upgrade/patch Resolve API usage — check the Resolve/Studio version's API for GetUniqueId support
- Re-acquire the timeline and retry after the append settles
- Inspect the track items to find the corrupted clip and remove/re-add it
- Extend identity() to reject/handle None early with a clearer probe of the item
Example fix
// before
method = getattr(candidate, "GetUniqueId", None)
return method() if callable(method) else id(candidate)
// after
method = getattr(candidate, "GetUniqueId", None)
uid = method() if callable(method) else None
if uid is None:
raise RuntimeError(f"item {candidate.GetName() if hasattr(candidate,'GetName') else candidate} has no unique id")
return uid Defensive patterns
Strategy: try-catch
Validate before calling
for item in members:
uid = item.GetUniqueId() if callable(getattr(item, "GetUniqueId", None)) else None
if uid is None:
raise RuntimeError(f"item {item.GetName()} has no unique id") Type guard
def has_identity(item) -> bool:
m = getattr(item, "GetUniqueId", None)
return callable(m) and m() is not None Try / catch
try:
result = apply_placements(...)
except RuntimeError as exc:
if "without an identity" in str(exc):
# re-acquire timeline and retry once
timeline = project.GetCurrentTimeline()
else:
raise Prevention
- Keep Resolve updated; GetUniqueId behavior varies across versions
- Re-acquire timeline objects after appends instead of caching them
- Avoid running concurrent API scripts against the same project
- Log item names when identity checks fail for easier diagnosis
When it happens
Trigger: _readback iterating track items where a member's GetUniqueId returns None or is not callable and the object wraps None; Resolve API returning placeholder/invalid clip objects after append.
Common situations: Resolve version with changed/removed GetUniqueId behavior returning None; corrupted clip after failed import; API object garbage-collected mid-readback in a long-running session.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- placement missing from requested track
- placement readback mismatch
- could not read track
- Invalid installState identity: expected targetId and…
- Invalid installState identity: targetId must be a non-empty…
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/ddb6edf3ff0938b7.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/resolve.py:202
}
for item in _items(timeline, kind, track)
]
return snapshot
def _readback(timeline, item, event):
track = event["track"]
members = _items(timeline, "video", track)
# API wrappers can be recreated on each call, so verify track membership by
# stable unique id when available; test doubles may use object identity.
def identity(candidate):
method = getattr(candidate, "GetUniqueId", None)
return method() if callable(method) else id(candidate)
item_id = identity(item)
if item_id is None:
raise RuntimeError("Resolve returned an item without an identity")
matches = [member for member in members if identity(member) == item_id]
if len(matches) != 1:
raise RuntimeError(f"placement {event['id']} missing from requested track")
item = matches[0]
actual = {
"start": item.GetStart(),
"end": item.GetEnd(),
"duration": item.GetDuration(),
"enabled": item.GetClipEnabled(),
"track": track,
"opacity": item.GetProperty("Opacity"),
"composite": item.GetProperty("CompositeMode"),
"path": _path(item),
}
expected = {
"start": event["record_frame"],
"end": event["record_frame"] + event["frames"],
"duration": event["frames"],View on GitHub (pinned to 8321021c54)