{"record":{"id":"80b8c2a09e5329a9","repo":"stride3d/stride","slug":"unable-to-find-a-serializer-for-the-specified-asset-no-asset","errorCode":null,"errorMessage":"Unable to find a serializer for the specified asset. No asset file extension registered to AssetRegistry","messagePattern":"Unable to find a serializer for the specified asset\\. No asset file extension registered to AssetRegistry","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/assets/Stride.Core.Assets/AssetFileSerializer.cs","lineNumber":150,"sourceCode":"    /// <summary>\n    /// Serializes an <see cref=\"Asset\" /> to the specified stream.\n    /// </summary>\n    /// <param name=\"stream\">The stream.</param>\n    /// <param name=\"asset\">The asset object.</param>\n    /// <param name=\"yamlMetadata\"></param>\n    /// <param name=\"log\">The logger.</param>\n    /// <exception cref=\"System.ArgumentNullException\">\n    /// stream\n    /// or\n    /// assetFileExtension\n    /// </exception>\n    public static void Save(Stream stream, object asset, AttachedYamlAssetMetadata? yamlMetadata, ILogger? log = null, string? assetNamespace = null)\n    {\n        ArgumentNullException.ThrowIfNull(stream);\n        if (asset == null) return;\n\n        var assetFileExtension = AssetRegistry.GetDefaultExtension(asset.GetType())\n            ?? throw new ArgumentException(\"Unable to find a serializer for the specified asset. No asset file extension registered to AssetRegistry\");\n        var serializer = FindSerializer(assetFileExtension)\n            ?? throw new InvalidOperationException($\"Unable to find a serializer for [{assetFileExtension}]\");\n        serializer.Save(stream, asset, yamlMetadata, log, assetNamespace);\n    }\n}\n","sourceCodeStart":132,"sourceCodeEnd":156,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/assets/Stride.Core.Assets/AssetFileSerializer.cs#L132-L156","documentation":"Save asks AssetRegistry.GetDefaultExtension for the file extension registered for the asset's concrete type; when the type has no registered default extension the library cannot pick a serializer and throws ArgumentException. Every asset type you save must be registered in the AssetRegistry.","triggerScenarios":"Calling AssetFileSerializer.Save with an object whose runtime type was never registered via an AssetUpgrader/Asset registration (no AssetDescription/extension mapping), e.g. a custom Asset subclass without registration, or a plain object mistaken for an asset.","commonSituations":"Creating a new custom Asset class and forgetting to register it with the asset registry/plugin; saving a base Asset instance; assembly containing the asset type not loaded at save time.","solutions":["Register the asset type with AssetRegistry so GetDefaultExtension returns an extension (via an AssetDescription / module registration)","Verify the asset's concrete type derives from Asset and its assembly is loaded","Ensure the default extension registered for the type also has a matching serializer (otherwise error 52 follows)","Log asset.GetType() before Save to confirm the type being saved"],"exampleFix":"// before\nAssetFileSerializer.Save(stream, new MyCustomAsset()); // unregistered type\n// after\n// in module/plugin init:\nAssetRegistry.RegisterFormat(new FileExtensionAssetDescription { AssetType = typeof(MyCustomAsset), FileExtension = \".myasset\" });\nAssetFileSerializer.Save(stream, new MyCustomAsset());","handlingStrategy":"validation","validationCode":"if (asset == null) return;\nvar ext = AssetRegistry.GetDefaultExtension(asset.GetType());\nif (ext == null) throw new ArgumentException($\"{asset.GetType()} has no registered default extension\");","typeGuard":"static bool IsRegisteredAsset(object a) => a is Asset && AssetRegistry.GetDefaultExtension(a.GetType()) != null;","tryCatchPattern":"try { AssetFileSerializer.Save(stream, asset, yamlMetadata, log); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"No asset file extension registered\"))\n{ log.Error($\"Asset type {asset.GetType()} is not registered\"); }","preventionTips":["Register every custom Asset type with AssetRegistry at module init","Keep the asset-type assembly loaded in the saving process","Test save of each asset type once during development"],"tags":["serialization","asset-registry","unregistered-type"],"backgroundTag":"invalid-argument-value","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}