{"record":{"id":"c212a816e4f4dfb1","repo":"dotnet/orleans","slug":"the-requested-vote-option-was-not-found","errorCode":null,"errorMessage":"The requested vote option was not found.","messagePattern":"The requested vote option was not found\\.","errorType":"exception","errorClass":"KeyNotFoundException","httpStatus":null,"severity":"error","filePath":"samples/Voting/Grains/VoteGrain.cs","lineNumber":55,"sourceCode":"        {\n            _logger.LogInformation(\"Recorded a vote for an existing option\");\n            _state.State[key] += 1;\n        }\n\n        await _state.WriteStateAsync();\n        _logger.LogInformation(\"Saved vote in {ElapsedMilliseconds}ms\", stopwatch.ElapsedMilliseconds);\n    }\n\n    public async Task RemoveVote(string option)\n    {\n        var stopwatch = Stopwatch.StartNew();\n        _logger.LogInformation(\"Deleting vote option\");\n\n        var key = option.ToLower();\n        if (!_state.State.ContainsKey(key))\n        {\n            _logger.LogWarning(\"Didn't find the requested vote option\");\n            throw new KeyNotFoundException(\"The requested vote option was not found.\");\n        }\n        else\n        {\n            _logger.LogInformation(\"Removed a vote option\");\n            _state.State.Remove(key.ToLower());\n        }\n\n        await _state.WriteStateAsync();\n\n        _logger.LogInformation(\"Deleted vote option {ElapsedMilliseconds}ms\", stopwatch.ElapsedMilliseconds);\n    }\n}\n","sourceCodeStart":37,"sourceCodeEnd":68,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/samples/Voting/Grains/VoteGrain.cs#L37-L68","documentation":"Thrown by Voting VoteGrain.RemoveVote when the lower-cased option key is not present in the grain's persisted state dictionary. KeyNotFoundException indicates the vote option you tried to delete does not exist (it was never created or already removed).","triggerScenarios":"A client calls voteGrain.RemoveVote(option) with an option string whose lower-cased form is not a key in _state.State.","commonSituations":"Calling RemoveVote before the option was added; calling it twice (the second time the key is gone); case mismatch where the stored key has different casing — note the grain lower-cases both stored and queried keys, so pure case alone should not trigger it, but a leading/trailing space would.","solutions":["Check that the option exists before removing, or treat its absence as success (make RemoveVote idempotent).","Avoid calling RemoveVote twice for the same option.","Trim and normalize the option string on the client before sending."],"exampleFix":"// before\npublic async Task RemoveVote(string option) {\n  if (!_state.State.ContainsKey(key)) throw new KeyNotFoundException(\"...\");\n  _state.State.Remove(key);\n}\n\n// after: idempotent remove\npublic async Task RemoveVote(string option) {\n  _state.State.Remove(option.ToLower());\n}","handlingStrategy":"validation","validationCode":"// Normalize and check existence before removing\nvar key = option.Trim().ToLower();\nif (!await vote.HasOption(key)) return;\nawait vote.RemoveVote(option);","typeGuard":"null","tryCatchPattern":"try { await vote.RemoveVote(option); }\ncatch (KeyNotFoundException) { /* already absent; treat as success */ }","preventionTips":["Make RemoveVote idempotent — treat missing keys as success.","Avoid removing the same option twice.","Trim and normalize option strings on the client."],"tags":["voting","validation","key-not-found","sample"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}