elsa-workflows/elsa-core · error · Exception

Failed to retrieve memory block with reference

Error message

Failed to retrieve memory block with reference {blockReference.Id}

What it means

ExpressionExecutionContext.GetBlock looks up the MemoryBlock that a MemoryBlockReference points to in the context's memory register. When the reference's Id does not resolve to an existing block, the internal lookup returns null and this generic Exception is thrown. It means a variable/argument reference was used but no storage slot was ever allocated for it in this execution scope or its parents.

Solutions

  1. Use TryGetBlock(ref, out var block) instead of GetBlock to handle missing blocks gracefully.
  2. Ensure the variable/argument is declared and set (ExecuteAsync with the variable or a SetVariable/Set value activity) before reading it.
  3. Verify the memory reference is obtained from the correct ExpressionExecutionContext / owner so its Id matches an allocated block.

Example fix

// before
var block = context.GetBlock(() => myVariable.GetReferenceTo(context));
// after
if (context.TryGetBlock(() => myVariable.GetReferenceTo(context), out var block))
{
    // use block
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (context.TryGetBlock(() => variable.GetReferenceTo(context), out var block)) { /* proceed */ } else { /* handle missing */ }

Type guard

static bool HasBlock(ExpressionExecutionContext ctx, MemoryBlockReference r) => ctx.TryGetBlock(r, out _);

Try / catch

try { var block = context.GetBlock(reference); } catch (Exception ex) when (ex.Message.StartsWith("Failed to retrieve memory block")) { /* allocate or fail gracefully */ }

Prevention

When it happens

Trigger: Calling ExpressionExecutionContext.GetBlock(Func<MemoryBlockReference>) or GetBlock(MemoryBlockReference) with a reference whose Id was never registered via memory allocation (e.g. a Variable that was not declared, or a reference created against a different context/owner).

Common situations: Referencing a variable from a workflow fragment executed in a context where the variable was never set; custom activities reading variables with GetBlock instead of Get<T>; expression code capturing a Variable object whose block was removed or never allocated in the current scope chain.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13). Data as JSON: /api/errors/95e05625e1e71fe3. Report an issue: GitHub.

Appendix: source

Thrown at src/modules/Elsa.Expressions/Models/ExpressionExecutionContext.cs:50

    /// <summary>
    /// Provides access to the parent <see cref="ExpressionExecutionContext"/>, if there is any.
    /// </summary>
    public ExpressionExecutionContext? ParentContext { get; set; } = parentContext;

    /// <summary>
    /// A cancellation token.
    /// </summary>
    public CancellationToken CancellationToken { get; } = cancellationToken;

    /// <summary>
    /// Returns the <see cref="MemoryBlock"/> pointed to by the specified memory block reference.
    /// </summary>
    public MemoryBlock GetBlock(Func<MemoryBlockReference> blockReference) => GetBlock(blockReference());

    /// <summary>
    /// Returns the <see cref="MemoryBlock"/> pointed to by the specified memory block reference.
    /// </summary>
    public MemoryBlock GetBlock(MemoryBlockReference blockReference) => GetBlockInternal(blockReference) ?? throw new Exception($"Failed to retrieve memory block with reference {blockReference.Id}");

    /// <summary>
    /// Returns the <see cref="MemoryBlock"/> pointed to by the specified memory block reference.
    /// </summary>
    public bool TryGetBlock(MemoryBlockReference blockReference, out MemoryBlock block)
    {
        var b = GetBlockInternal(blockReference);
        block = b ?? null!;
        return b != null;
    }

    /// <summary>
    /// Returns the value of the memory block pointed to by the specified memory block reference.
    /// </summary>
    public object? Get(Func<MemoryBlockReference> blockReference) => Get(blockReference());

    /// <summary>
    /// Returns the value of the memory block pointed to by the specified memory block reference.

View on GitHub (pinned to fe9217bdfa)