louthy/language-ext · error · NullReferenceException

Activity is null

Error message

Activity is null

What it means

Activity.startActivity wraps System.Diagnostics.ActivitySource.StartActivity, which returns null when there is no listener registered for the activity source (i.e. no OpenTelemetry/ActivityListener is sampling that source). LanguageExt's Activity<M,RT> facade treats a null result as a failure and throws NullReferenceException("Activity is null") instead of silently continuing without tracing.

Solutions

  1. Register an ActivityListener (or configure OpenTelemetry with AddSource("<source-name>")) before running the span-wrapped operation, using the same source name the RT provides via ActivitySourceIO.
  2. Use Activity.span rather than calling startActivity directly; if you call it directly, accept that a null Activity (no listener) is fatal in this facade and either guard with currentActivity/listener checks or avoid it.
  3. Verify the OTel sampler is not set to Drop/None and that the listener's Source filter (ShouldListenTo) matches the source name.
  4. If tracing is intentionally disabled, wrap span usage behind a flag so the traced code path is not executed without a listener.

Example fix

// before
var program = Activity<IO, Runtime>.span("do-work", work);
program.Run(runtime); // throws "Activity is null" when no listener

// after
using var listener = new ActivityListener
{
    ShouldListenTo = s => s.Name == "my-source",
    Sample = (ref ActivityCreationOptions<ActivityContext> _) => ActivitySamplingResult.AllData,
    ActivityStarted = _ => { }
};
ActivitySource.AddActivityListener(listener);
var program = Activity<IO, Runtime>.span("do-work", work);
program.Run(runtime);
Defensive patterns

Strategy: try-catch

Validate before calling

// Check that a listener exists before running traced code:
var hasListener = ActivitySource.HasListeners(); // System.Diagnostics helper (or track via ActivitySourceIO)
if (!hasListener) { /* skip tracing or initialize OTel first */ }

Type guard

static bool CanTrace(Runtime rt) =>
    ActivitySource.HasListeners() && rt.Source.Name != null;

Try / catch

try
{
    return program.Run(runtime); // program uses Activity.span
}
catch (NullReferenceException e) when (e.Message == "Activity is null")
{
    // no ActivityListener registered for the source; run untraced or initialize OTel
    return fallbackProgram.Run(runtime);
}

Prevention

When it happens

Trigger: Calling Activity.span/startActivity (directly or via LanguageExt.Sys runtime effects) while no ActivityListener is registered for the ActivitySource name in the runtime's ActivitySourceIO — e.g. tracing enabled in code but the OTel SDK/listener not configured, or the source name filtered out by the listener.

Common situations: Running an Eff/Aff program with Activity.span in tests or local runs without OpenTelemetry instrumentation initialized; mismatch between the ActivitySource name registered in the runtime and the name the listener subscribes to; deploying with OTel SDK absent or SetSampler suppressing all (None sampler); calling startActivity manually instead of via span.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of louthy/language-ext@2f0e362824 (2026-09-15). Data as JSON: /api/errors/60b6f473099df5ca. Report an issue: GitHub.

Appendix: source

Thrown at LanguageExt.Sys/Sys/Diag/Activity.cs:51

    public static K<M, Activity> startActivity(
        string name,
        ActivityKind activityKind,
        HashMap<string, object> activityTags,
        Seq<ActivityLink> activityLinks,
        DateTimeOffset startTime,
        ActivityContext? parentContext = null) =>
        from src in activityIO
        from cur in currentActivity
        from act in use(src.StartActivity(
                            name,
                            activityKind,
                            cur is null
                                ? default
                                : parentContext ?? cur.Context,
                            activityTags,
                            activityLinks,
                            startTime).Map(a => a ?? throw new NullReferenceException("Activity is null")))
        select act;

    /// <summary>
    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent
    /// activity context, tags, optional activity link and optional start time.
    /// </summary>
    /// <param name="name">The operation name of the activity.</param>
    /// <param name="operation">The operation to whose activity will be traced</param>
    /// <returns>The result of the `operation`</returns>
    public static K<M, A> span<A>(string name, K<M, A> operation) =>
        span(name, ActivityKind.Internal, default, default, DateTimeOffset.Now, operation);

    /// <summary>
    /// Creates a new activity if there are active listeners for it, using the specified name, activity kind, parent
    /// activity context, tags, optional activity link and optional start time.
    /// </summary>
    /// <param name="name">The operation name of the activity.</param>
    /// <param name="activityKind">The activity kind.</param>

View on GitHub (pinned to 2f0e362824)