stride3d/stride · error · InvalidOperationException

content reference(s) were not rooted (see errors above)…

Error message

{mismatches} content reference(s) were not rooted (see errors above); this would break bundling and runtime loading.

What it means

ObjectNode.Remove supports only CollectionDescriptor and DictionaryDescriptor node types; when the Descriptor is neither, it throws NotSupportedException. Sets and other unsupported collection kinds cannot have items removed through this API.

Solutions

  1. Verify the Descriptor is CollectionDescriptor or DictionaryDescriptor before calling Remove.
  2. For set-backed nodes, replace the set value via Update/SetValue instead of removing an element.
  3. Implement or register a descriptor for custom collection types if removal support is required.

Example fix

// before
node.Remove(unwantedItem, itemIndex);
// after
if (node.Descriptor is CollectionDescriptor || node.Descriptor is DictionaryDescriptor)
    node.Remove(unwantedItem, itemIndex);
Defensive patterns

Strategy: validation

Validate before calling

bool canRemove = node.Descriptor is CollectionDescriptor { HasRemoveAt: true } or DictionaryDescriptor;
if (!canRemove) throw new InvalidOperationException("Node does not support item removal");

Type guard

bool IsRemovableCollection(ObjectNode node) => node.Descriptor is CollectionDescriptor or DictionaryDescriptor;

Try / catch

try { node.Remove(item, itemIndex); }
catch (NotSupportedException ex) { /* replace the whole value via Update/SetValue instead */ }

Prevention

When it happens

Trigger: Calling ObjectNode.Remove(item, index) on a node whose Descriptor is not a CollectionDescriptor (with HasRemoveAt path) and not a DictionaryDescriptor — e.g. a set-backed node or an unrecognized custom collection.

Common situations: Generic 'delete selected item' handlers in editors that invoke Remove for every collection-like node, including sets; removing from custom collection types lacking descriptor support.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/7cf588b03bdf54ed. Report an issue: GitHub.

Appendix: source

Thrown at sources/assets/Stride.AssetCompiler/BundlePacker.cs:358

                    // (a target in a bare package is meant to stay bare).
                    if (reference.Length == 0 || reference[0] == '/' || contentIndexMap.TryGetValue(reference, out _))
                        continue;

                    // Bare and not found as-is: flag it only if the rooted version is in the index.
                    foreach (var assetNamespace in assetNamespaces)
                    {
                        if (contentIndexMap.TryGetValue("/" + assetNamespace + "/" + reference, out _))
                        {
                            logger.Error($"Content '{entry.Key}' references '{reference}' without its /namespace/ prefix, but that target is indexed as '/{assetNamespace}/{reference}'. The reference was not rooted.");
                            mismatches++;
                            break;
                        }
                    }
                }
            }

            if (mismatches > 0)
                throw new InvalidOperationException($"{mismatches} content reference(s) were not rooted (see errors above); this would break bundling and runtime loading.");
        }

        /// <summary>
        /// Gets and cache the asset url referenced by the chunk with the given identifier.
        /// </summary>
        /// <param name="objectId">The object identifier.</param>
        /// <returns>The list of asset url referenced.</returns>
        private List<string> GetChunkReferences(DatabaseFileProvider databaseFileProvider, ref ObjectId objectId)
        {
            List<string> references;

            // Check the cache
            if (!referencesByObjectId.TryGetValue(objectId, out references))
            {
                // First time, need to scan it
                referencesByObjectId[objectId] = references = new List<string>();

                // Open stream to read list of chunk references

View on GitHub (pinned to 96fad776d2)