{"record":{"id":"b7bfaa0775e8f7cc","repo":"OrchardCMS/OrchardCore","slug":"an-uninitialized-or-default-valuestopwatch-cannot-be-used-to","errorCode":null,"errorMessage":"An uninitialized, or 'default', ValueStopwatch cannot be used to get elapsed time.","messagePattern":"An uninitialized, or 'default', ValueStopwatch cannot be used to get elapsed time\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore/Modules/Overrides/HttpClient/ValueStopwatch.cs","lineNumber":27,"sourceCode":"{\n    private readonly long _startTimestamp;\n\n    public readonly bool IsActive => _startTimestamp != 0;\n\n    private ValueStopwatch(long startTimestamp)\n    {\n        _startTimestamp = startTimestamp;\n    }\n\n    public static ValueStopwatch StartNew() => new(Stopwatch.GetTimestamp());\n\n    public TimeSpan GetElapsedTime()\n    {\n        // Start timestamp can't be zero in an initialized ValueStopwatch. It would have to be literally the first thing executed when the machine boots to be 0.\n        // So it being 0 is a clear indication of default(ValueStopwatch).\n        if (!IsActive)\n        {\n            throw new InvalidOperationException(\"An uninitialized, or 'default', ValueStopwatch cannot be used to get elapsed time.\");\n        }\n\n        var end = Stopwatch.GetTimestamp();\n\n        return Stopwatch.GetElapsedTime(_startTimestamp, end);\n    }\n}\n","sourceCodeStart":9,"sourceCodeEnd":35,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore/Modules/Overrides/HttpClient/ValueStopwatch.cs#L9-L35","documentation":"ValueStopwatch is a struct wrapper around Stopwatch.GetTimestamp. A default(ValueStopwatch) has _startTimestamp == 0, meaning it was never started; GetElapsedTime refuses to compute a meaningless elapsed time and throws InvalidOperationException when IsActive is false.","triggerScenarios":"Calling GetElapsedTime() on a ValueStopwatch that was never initialized via ValueStopwatch.StartNew() — e.g., an uninitialized field, a struct copied before StartNew, or a default-constructed struct passed into a method.","commonSituations":"Field declared but StartNew never called on some code path; Stopwatch struct stored in a dictionary and retrieved before insertion; default struct returned from a Try-pattern failure branch.","solutions":["Initialize with ValueStopwatch.StartNew() before any GetElapsedTime call.","Check the IsActive property before calling GetElapsedTime and handle the inactive case.","Make the field nullable or wrap it in a class so an uninitialized state is explicit.","Audit failure/early-return paths that skip StartNew but still flow into timing code."],"exampleFix":"// before\nprivate ValueStopwatch _stopwatch;\npublic void Done() => Log(_stopwatch.GetElapsedTime()); // throws if never started\n\n// after\nprivate ValueStopwatch? _stopwatch;\npublic void Begin() => _stopwatch = ValueStopwatch.StartNew();\npublic void Done() { if (_stopwatch is { IsActive: true }) Log(_stopwatch.Value.GetElapsedTime()); }","handlingStrategy":"type-guard","validationCode":"if (!stopwatch.IsActive)\n    throw new InvalidOperationException(\"Stopwatch was never started.\");","typeGuard":"bool CanReadElapsed(in ValueStopwatch stopwatch) => stopwatch.IsActive;","tryCatchPattern":"try { var elapsed = stopwatch.GetElapsedTime(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"uninitialized\"))\n{\n    _logger.LogWarning(\"Attempted to read elapsed time from a default ValueStopwatch\");\n}","preventionTips":["Always initialize with ValueStopwatch.StartNew(), never default.","Check IsActive before GetElapsedTime on fields that may be uninitialized.","Wrap ValueStopwatch in a nullable field or factory-allocated holder so zero-value state is impossible to miss.","Audit early-return code paths that skip StartNew."],"tags":["diagnostics","stopwatch","struct","uninitialized"],"backgroundTag":"internal-invariant-violation","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}