Open sandboxFocusImprove this doc

LAMA0872: A durable parameter receives an argument that is not durable

Severity Warning
Reported by Metalama.Framework (Roslyn analyzer)
Message The parameter '<Parameter>' is marked [Durable] but the argument is of type '<ArgumentType>', which is not durable. Retention path: <RetentionPath>.

Cause

Applying [Durable] (defined in the Metalama.Framework.Utilities namespace) to a parameter means that the method or constructor may keep the argument beyond the call, and that every argument passed at every call site must therefore be safe to keep across compilations. A durable value must not hold a compilation, a syntax tree, a symbol, a semantic model, or anything that reaches one. See LAMA0870 for the full rationale.

Metalama reports LAMA0872 when an argument passed to a parameter marked [Durable] has a type that isn't durable. The analyzer checks every argument of a method call or of an object creation, whether it is positional, named, optional, or part of a params array. The warning is reported on the argument expression. In the message, <Parameter> is the name of the parameter, <ArgumentType> is the type of the argument, and <RetentionPath> is the chain of types that explains why it isn't durable, followed by the reason in parentheses.

When the argument is a lambda expression, the analyzer examines the variables that the lambda captures, because a lambda holds its closure. In that case, it reports a different diagnostic, LAMA0878, at the captured variable.

The analyzer runs in the compiler and in the IDE, not in the Metalama aspect pipeline, so this diagnostic can't be shown in an example that runs a Metalama aspect test.

Resolution

  • Pass a durable value. Pass an IDurableRef (call ToDurableRef() on a declaration), a SerializableDeclarationId, or a string, instead of the symbol, the syntax node, or the declaration.
  • Use DurableDangerous<T>. If the value is durable in fact but the analyzer can't establish it, wrap it in DurableDangerous<T>.
  • Remove [Durable] from the parameter if the method doesn't keep the argument beyond the call.

See also