{"record":{"id":"377f3ce61c77906f","repo":"devlooped/moq","slug":"invalidoperationexception-unhandled-times-kind-in-tostring","errorCode":null,"errorMessage":"InvalidOperationException (unhandled Times kind in ToString)","messagePattern":"InvalidOperationException \\(unhandled Times kind in ToString\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Moq/Times.cs","lineNumber":255,"sourceCode":"        {\n            return !left.Equals(right);\n        }\n\n        /// <inheritdoc/>\n        public override string ToString()\n        {\n            return this.kind switch\n            {\n                Kind.AtLeastOnce => \"AtLeastOnce\",\n                Kind.AtLeast => $\"AtLeast({this.from})\",\n                Kind.AtMost => $\"AtMost({this.to})\",\n                Kind.AtMostOnce => \"AtMostOnce\",\n                Kind.BetweenExclusive => $\"Between({this.from - 1}, {this.to + 1}, Exclusive)\",\n                Kind.BetweenInclusive => $\"Between({this.from}, {this.to}, Inclusive)\",\n                Kind.Exactly => $\"Exactly({this.from})\",\n                Kind.Once => \"Once\",\n                Kind.Never => \"Never\",\n                _ => throw new InvalidOperationException(),\n            };\n        }\n\n        internal string GetExceptionMessage(int callCount)\n        {\n            var (from, to) = this;\n\n            if (this.kind == Kind.BetweenExclusive)\n            {\n                --from;\n                ++to;\n            }\n\n            var message = this.kind switch\n            {\n                Kind.AtLeastOnce => Resources.NoMatchingCallsAtLeastOnce,\n                Kind.AtLeast => Resources.NoMatchingCallsAtLeast,\n                Kind.AtMost => Resources.NoMatchingCallsAtMost,","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/devlooped/moq/blob/89a5be629c752960fe403e95ff583e4ae6f00542/src/Moq/Times.cs#L237-L273","documentation":"Times.ToString() switches over the internal Kind enum and throws InvalidOperationException when no case matches. This is an internal invariant violation — a Times value with a kind outside the known enum members reached ToString.","triggerScenarios":"A Times struct created with an undefined Kind (e.g. invalid cast, default-initialized/partially constructed value, reflection or deserialization of garbage), then rendered via ToString or interpolated into a message.","commonSituations":"Custom test frameworks or serialization tools constructing Times incorrectly; binary/formatter deserialization of Moq internals; Moq version mismatches where an enum value from one version meets code from another.","solutions":["Never construct Times via new Times(...) internals — only use the static factories (Exactly, AtLeast, Between, Once, Never, etc.)","Check for mixed Moq assembly versions (binding redirects / NuGet unify to a single version)","If hit without custom construction, it indicates corrupted state or a Moq bug — file an issue with a repro"],"exampleFix":"// before\nvar t = (Times)Activator.CreateInstance(typeof(Times), (Times.Kind)999, 0, 0); // invalid kind\n// after\nvar t = Times.Exactly(3);","handlingStrategy":"type-guard","validationCode":"// only build Times via public factories\nTimes t = Times.Exactly(3); // safe\n// avoid: raw construction, casting ints to Times.Kind","typeGuard":"static bool IsValidTimes(Times t) =>\n    new[] { \"AtLeast\", \"AtLeastOnce\", \"AtMost\", \"AtMostOnce\", \"Between\", \"Exactly\", \"Once\", \"Never\" }\n        .Any(k => { try { return t.ToString().StartsWith(k); } catch (InvalidOperationException) { return false; } });","tryCatchPattern":"try\n{\n    Console.WriteLine(times);\n}\ncatch (InvalidOperationException)\n{\n    // invalid Times kind — rebuild from a factory\n    times = Times.AtLeastOnce();\n}","preventionTips":["Construct Times only via its static factories","Keep a single Moq package version across projects","Never persist/deserialize Times values"],"tags":["invalid-enum-value","moq","internal-invariant"],"backgroundTag":"invalid-enum-value","analyzedSha":"89a5be629c752960fe403e95ff583e4ae6f00542","analyzedAt":"2026-09-16T05:31:39.496Z","contentChangedAt":"2026-09-16T05:31:39.496Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}