microsoft/aspire · error · ArgumentNullException
Object reference not passed for parameter 'callback'…
Error message
Object reference not passed for parameter 'callback' (ArgumentNullException: callback)
What it means
RustCargoArgsCallbackAnnotation's constructor validates its 'callback' parameter with ArgumentNullException.ThrowIfNull and its Callback property initializer repeats the guard. The library requires a non-null delegate because the annotation is invoked later during cargo argument construction; a null callback would crash the pipeline far from the misuse site. The exception names the offending parameter so the mistake is caught at annotation creation time.
Solutions
- Pass a non-null async lambda when creating the annotation, e.g. args => Task.CompletedTask if no customization is needed
- Check any intermediate variable holding the callback for null before constructing the annotation
- Move the annotation registration inside the branch where the callback is actually created
Example fix
// before Func<RustCargoArgsCallbackContext, Task> callback = condition ? ConfigureArgs : null; var annotation = new RustCargoArgsCallbackAnnotation(callback); // after Func<RustCargoArgsCallbackContext, Task> callback = condition ? ConfigureArgs : static _ => Task.CompletedTask; var annotation = new RustCargoArgsCallbackAnnotation(callback);
Defensive patterns
Strategy: validation
Validate before calling
if (callback is null) throw new InvalidOperationException("Cargo args callback must be assigned before creating RustCargoArgsCallbackAnnotation."); Type guard
bool HasCallback(Func<RustCargoArgsCallbackContext, Task>? cb) => cb is not null;
Try / catch
try { var ann = new RustCargoArgsCallbackAnnotation(cb); } catch (ArgumentNullException ex) when (ex.ParamName == "callback") { log.LogError(ex, "Null cargo args callback"); } Prevention
- Default conditional callbacks to a no-op lambda (static _ => Task.CompletedTask) instead of null
- Never store callbacks in nullable fields without a null check at the construction site
- Construct annotations inside the branch where the delegate is actually created
When it happens
Trigger: Calling new RustCargoArgsCallbackAnnotation(resource, callback, ...) (or the WithCargoArgsCallback-style extension that constructs it) with a null Func<RustCargoArgsCallbackContext, Task>, typically from an uninitialized delegate field or a helper that conditionally assigns the callback.
Common situations: Conditional fluent configuration where the callback is only assigned in one branch; a lambda variable that is still null at annotation-creation time; refactoring that removed the lambda but left the call passing the now-null variable.
Related errors
- ArgumentNullException for parameter 'callback' (callback is…
- Object reference not passed for parameter 'args'…
- Object reference not passed for parameter 'resource'…
- sourcePath
- ArgumentNullException for parameter 'callback' (callback is…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/95b8e07bd9e9d985.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Rust/RustCargoArgsCallbackAnnotation.cs:31
{
/// <summary>
/// Initializes a new instance of the <see cref="RustCargoArgsCallbackAnnotation"/> class.
/// </summary>
/// <param name="callback">The callback action to be executed.</param>
public RustCargoArgsCallbackAnnotation(Action<IList<string>> callback)
: this(context =>
{
callback(context.Args);
return Task.CompletedTask;
})
{
ArgumentNullException.ThrowIfNull(callback);
}
/// <summary>
/// Gets the callback action that is executed to populate cargo-level arguments.
/// </summary>
public Func<RustCargoArgsCallbackContext, Task> Callback { get; } = callback ?? throw new ArgumentNullException(nameof(callback));
}
/// <summary>
/// Represents callback context for cargo-level command-line arguments.
/// </summary>
/// <param name="resource">The Rust application resource whose cargo arguments are being built.</param>
/// <param name="args">The command-line arguments collection.</param>
/// <param name="cancellationToken">The cancellation token associated with this callback context.</param>
/// <remarks>
/// Unlike program arguments, cargo arguments are plain strings rather than <see cref="object"/>.
/// They select build behaviour (<c>--release</c>, <c>--features</c>, <c>--bin</c>) before the program
/// starts, so there is nothing for a deferred value such as an endpoint reference to resolve against;
/// those belong after the <c>--</c> separator and are added with <c>WithArgs</c>.
/// </remarks>
public sealed class RustCargoArgsCallbackContext(RustAppResource resource, IList<string> args, CancellationToken cancellationToken = default)
{
/// <summary>
/// Gets the Rust application resource whose cargo arguments are being built.View on GitHub (pinned to 25830f84bd)