stride3d/stride · error · ArgumentException
The relativePath argument is null or empty
Error message
The relativePath argument is null or empty
What it means
The protected helper GetAbsolutePath combines a relative path with the parent directory of the asset's FullPath to produce an absolute on-disk path. It guards against a null or empty UFile argument by throwing ArgumentException, since combining an empty path is meaningless.
Solutions
- Ensure the asset's source path property (e.g. Yolo/Source) is set before compilation.
- Guard with string.IsNullOrEmpty(relativePath) in the compiler and log a proper error instead of passing it through.
- Fix asset deserialization so missing path fields get a default or are reported as a validation error.
- If the path should be optional, skip GetAbsolutePath when empty instead of calling it.
Example fix
// before
var abs = GetAbsolutePath(assetItem, asset.Source); // Source is empty UFile
// after
if (!string.IsNullOrEmpty(asset.Source))
{
var abs = GetAbsolutePath(assetItem, asset.Source);
}
else
{
logger.Error($"Asset {assetItem.Location} is missing its source path.");
} Defensive patterns
Strategy: validation
Validate before calling
if (string.IsNullOrEmpty(asset.Source))
{
logger.Error($"Asset {assetItem.Location} has no source path set.");
return;
}
var abs = GetAbsolutePath(assetItem, asset.Source); Type guard
static bool HasSourcePath(UFile relativePath) => !string.IsNullOrEmpty(relativePath);
Try / catch
try
{
var abs = GetAbsolutePath(assetItem, asset.Source);
}
catch (ArgumentException ex)
{
logger.Error($"Missing source path for asset {assetItem.Location}: {ex.Message}");
} Prevention
- Make source path fields required in asset templates and the editor.
- Validate asset fields (source paths not empty) during asset import/save.
- When deserializing, treat an empty expected-path field as an error instead of silently continuing.
When it happens
Trigger: Calling GetAbsolutePath(assetItem, relativePath) from a custom asset compiler with an uninitialized or empty UFile — e.g. a source/import path field on the asset was never set (default UFile is empty string).
Common situations: Asset YAML missing the expected source path field so it deserializes to an empty UFile; user cleared the 'Source' field in the editor; a compiler reading the wrong (unused) property as its relative path.
Related errors
- assetItem must be an absolute path
- Type [ ] must be assignable to Asset
- The BuildSteps property cannot be set to null
- Base path must be absolute, got
- vertexDeclaration
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/c3b84a455a2da436.
Report an issue: GitHub.
Appendix: source
Thrown at sources/assets/Stride.Core.Assets/Compiler/AssetCompilerBase.cs:85
/// <summary>
/// Compiles the asset from the specified package.
/// </summary>
/// <param name="context">The context to use to compile the asset.</param>
/// <param name="assetItem">The asset to compile</param>
/// <param name="targetUrlInStorage">The absolute URL to the asset, relative to the storage.</param>
/// <param name="result">The result where the commands and logs should be output.</param>
protected abstract void Prepare(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result);
/// <summary>
/// Returns the absolute path on the disk of an <see cref="UFile"/> that is relative to the asset location.
/// </summary>
/// <param name="assetItem">The asset on which is based the relative path.</param>
/// <param name="relativePath">The path relative to the asset path that must be converted to an absolute path.</param>
/// <returns>The absolute path on the disk of the <paramref name="relativePath"/> argument.</returns>
/// <exception cref="ArgumentException">The <paramref name="relativePath"/> argument is a null or empty <see cref="UFile"/>.</exception>
protected static UFile GetAbsolutePath(AssetItem assetItem, UFile relativePath)
{
if (string.IsNullOrEmpty(relativePath)) throw new ArgumentException("The relativePath argument is null or empty");
var assetDirectory = assetItem.FullPath.GetParent();
var assetSource = UPath.Combine(assetDirectory, relativePath);
return assetSource;
}
/// <summary>
/// Ensures that the sources of an <see cref="Asset"/> exist.
/// </summary>
/// <param name="result">The <see cref="AssetCompilerResult"/> in which to output log of potential errors.</param>
/// <param name="assetItem">The asset to check.</param>
/// <returns><c>true</c> if the source file exists, <c>false</c> otherwise.</returns>
/// <exception cref="ArgumentNullException">Any of the argument is <c>null</c>.</exception>
private static bool EnsureSourcesExist(AssetCompilerResult result, AssetItem assetItem)
{
ArgumentNullException.ThrowIfNull(result);
ArgumentNullException.ThrowIfNull(assetItem);
var collector = new SourceFilesCollector();View on GitHub (pinned to 96fad776d2)