{"record":{"id":"72ec6409ca7272a0","repo":"stride3d/stride","slug":"assetid-and-objectid-cannot-both-be-empty","errorCode":null,"errorMessage":"{assetId} and {objectId} cannot both be empty.","messagePattern":"(.+?) and (.+?) cannot both be empty\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/core/Stride.Core.Design/AbsoluteId.cs","lineNumber":24,"sourceCode":"\nnamespace Stride.Core;\n\n/// <summary>\n/// Represents the absolute identifier of an identifiable object in an asset.\n/// </summary>\n[DataContract(\"AbsoluteId\")]\npublic readonly struct AbsoluteId : IEquatable<AbsoluteId>\n{\n    /// <summary>\n    /// Initializes a new instance of <see cref=\"AbsoluteId\"/>.\n    /// </summary>\n    /// <param name=\"assetId\"></param>\n    /// <param name=\"objectId\"></param>\n    /// <exception cref=\"ArgumentException\"><paramref name=\"assetId\"/> and <paramref name=\"objectId\"/> cannot both be empty.</exception>\n    public AbsoluteId(AssetId assetId, Guid objectId)\n    {\n        if (assetId == AssetId.Empty && objectId == Guid.Empty)\n            throw new ArgumentException($\"{nameof(assetId)} and {nameof(objectId)} cannot both be empty.\");\n\n        AssetId = assetId;\n        ObjectId = objectId;\n    }\n\n    /// <summary>\n    /// The identifier of the containing asset.\n    /// </summary>\n    public AssetId AssetId { get; }\n\n    /// <summary>\n    /// The identifier of the object in the asset.\n    /// </summary>\n    public Guid ObjectId { get; }\n\n    public static bool operator ==(AbsoluteId left, AbsoluteId right)\n    {\n        return left.Equals(right);","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/core/Stride.Core.Design/AbsoluteId.cs#L6-L42","documentation":"The AbsoluteId constructor throws this ArgumentException when both the AssetId and the Guid objectId are empty. An AbsoluteId is meant to uniquely identify an object within an asset, so at least one of the two identifiers must be set. This is a fail-fast guard against meaningless identity values.","triggerScenarios":"Calling `new AbsoluteId(AssetId.Empty, Guid.Empty)` — e.g. both identifiers came from uninitialized fields, default(T), or deserialization that produced empty values.","commonSituations":"Deserializing broken/partial asset data, creating placeholder objects before an asset is loaded, using `default` struct initialization instead of a proper id.","solutions":["Ensure at least one of assetId or objectId is non-empty before constructing the AbsoluteId","Generate a real objectId via Guid.NewGuid() if the asset id is unknown","Fix the upstream deserialization/initialization path that left both identifiers empty"],"exampleFix":"// before\nvar id = new AbsoluteId(AssetId.Empty, Guid.Empty); // throws\n// after\nvar id = new AbsoluteId(assetId, Guid.NewGuid());","handlingStrategy":"validation","validationCode":"if (assetId == AssetId.Empty && objectId == Guid.Empty)\n    throw new ArgumentException(\"At least one of assetId or objectId must be set.\");\nvar id = new AbsoluteId(assetId, objectId);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never use default field values for identifiers; initialize Guids with Guid.NewGuid()","Validate deserialized ids before constructing domain objects"],"tags":["csharp","stride"],"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"}