{"record":{"id":"aa0cad35e2ada4a2","repo":"dotnetcore/CAP","slug":"specified-method-is-not-supported-circularbuffer","errorCode":null,"errorMessage":"Specified method is not supported.","messagePattern":"Specified method is not supported\\.","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"src/DotNetCore.CAP.Dashboard/CircularBuffer.cs","lineNumber":155,"sourceCode":"        }\n        else\n        {\n            itemIndex = _firstIndex + Count;\n            Count++;\n        }\n\n        _items[itemIndex] = item;\n    }\n\n    public void Clear()\n    {\n        _firstIndex = 0;\n        Count = 0;\n    }\n\n    public bool Contains(T item)\n    {\n        throw new NotImplementedException();\n    }\n\n    public void CopyTo(T[] array, int arrayIndex)\n    {\n        if (array == null) throw new ArgumentNullException(nameof(array));\n\n        if (arrayIndex < 0) throw new ArgumentOutOfRangeException(nameof(arrayIndex));\n\n        if (Count > array.Length - arrayIndex) throw new ArgumentException(\"arrayIndex\");\n\n        // Iterate through the buffer in correct order.\n        foreach (var item in this)\n        {\n            array[arrayIndex++] = item;\n        }\n    }\n\n    public bool Remove(T item)","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/dotnetcore/CAP/blob/e52b8508e54cdb7a9ce7f9fec03d9ea8ad2710fb/src/DotNetCore.CAP.Dashboard/CircularBuffer.cs#L137-L173","documentation":"CircularBuffer<T>.Contains(T item) is a stub that unconditionally throws NotImplementedException, surfaced as NotSupportedException (\"Specified method is not supported.\") via the ICollection<T> contract. The Dashboard's in-memory ring buffer simply never implemented membership testing. Calling it will always fail regardless of arguments.","triggerScenarios":"Calling Contains(item) on any CircularBuffer<T> instance, e.g. code that treats the buffer as an ICollection<T>/IReadOnlyCollection<T> and invokes Contains for membership checks.","commonSituations":"LINQ chains that resolve to ICollection<T>.Contains (e.g. some Contains optimizations), custom dashboard code checking whether a message/id is already buffered, or generic collection algorithms that probe for membership before insert.","solutions":["Do not call Contains on CircularBuffer; implement the membership check in caller code by iterating the buffer manually.","Implement Contains in CircularBuffer by iterating items and using EqualityComparer<T>.Default.Equals.","If reached via LINQ, force enumeration with AsEnumerable() or ToList() first so a different Contains path is used.","Upgrade DotNetCore.CAP in case a newer version implemented the method."],"exampleFix":"// before\nif (buffer.Contains(messageId)) { ... }\n// after\nbool contains = false;\nforeach (var item in buffer)\n{\n    if (EqualityComparer<string>.Default.Equals(item, messageId)) { contains = true; break; }\n}\nif (contains) { ... }","handlingStrategy":"validation","validationCode":"if (buffer is CircularBuffer<T> cb) { /* Contains unsupported */ }\n// do membership check manually:\nbool contains = false;\nforeach (var item in buffer) if (EqualityComparer<T>.Default.Equals(item, target)) { contains = true; break; }","typeGuard":"static bool SupportsContains<T>(ICollection<T> c) => !(c is DotNetCore.CAP.Dashboard.CircularBuffer<T>);","tryCatchPattern":"try { buffer.Contains(item); }\ncatch (NotImplementedException) { /* fall back to manual scan */ }","preventionTips":["Avoid LINQ Contains on CircularBuffer instances","Wrap buffer in your own helper that implements membership via iteration","Check the type before using generic ICollection<T> algorithms"],"tags":["not-implemented","collection","dashboard","dotnet"],"backgroundTag":"method-not-implemented","analyzedSha":"e52b8508e54cdb7a9ce7f9fec03d9ea8ad2710fb","analyzedAt":"2026-09-14T14:46:34.677Z","contentChangedAt":"2026-09-14T14:46:34.677Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}