{"record":{"id":"52baa09f8dda51a4","repo":"dotnet/orleans","slug":"the-frontend-cant-support-more-than-6-silos","errorCode":null,"errorMessage":"The frontend cant support more than 6 silos","messagePattern":"The frontend cant support more than 6 silos","errorType":"http","errorClass":"NotSupportedException","httpStatus":500,"severity":"warning","filePath":"playground/ActivationRebalancing/ActivationRebalancing.Frontend/Controllers/StatsController.cs","lineNumber":29,"sourceCode":"    [HttpGet(\"silos\")]\n    public async Task<IActionResult> GetStats()\n    {\n        var grainStats = await clusterClient\n            .GetGrain<IManagementGrain>(0)\n            .GetDetailedGrainStatistics();\n\n        var siloData = grainStats.GroupBy(stat => stat.SiloAddress)\n            .Select(g => new SiloData(g.Key.ToString(), g.Count()))\n            .ToList();\n\n        if (siloData.Count == 4)\n        {\n            siloData = [.. siloData, new SiloData(\"x\", 0)];\n        }\n\n        if (siloData.Count > 5)\n        {\n            throw new NotSupportedException(\"The frontend cant support more than 6 silos\");\n        }\n\n        return Ok(siloData);\n    }\n}\n\npublic record SiloData(string Host, int Activations);","sourceCodeStart":11,"sourceCodeEnd":36,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/playground/ActivationRebalancing/ActivationRebalancing.Frontend/Controllers/StatsController.cs#L11-L36","documentation":"This NotSupportedException is thrown by the ActivationRebalancing playground frontend's StatsController when the Orleans cluster returns detailed grain statistics for more than 5 distinct silos. The playground's chart UI (hard-coded line paths/colors for d3.js) was only built to render a fixed number of silo series, so the controller rejects oversized result sets rather than producing a broken visualization. The guard at line 27 caps siloData.Count at 5 (a literal '6 silos' message is slightly off-by-one versus the check).","triggerScenarios":"A GET /api/stats/silos request resolves, IManagementGrain.GetDetailedGrainStatistics() returns grain stats whose GroupBy(SiloAddress) yields more than 5 distinct silo addresses. This happens when the playground AppHost has been scaled up beyond the 4-5 silos the sample was designed to demo.","commonSituations":"Running the ActivationRebalancing playground with a larger cluster (e.g., manually adding more silo replicas or running against a shared dev cluster). Modifying the AppHost replica count without updating the frontend's hardcoded chart series.","solutions":["Reduce the cluster to 5 or fewer silos (the sample's intended size) and re-request /api/stats/silos.","If you intentionally need more silos, extend the frontend: increase the d3 linePaths/activationsHistory arrays in index.html and raise the > 5 cap in StatsController to match.","Generalize the chart to build its series dynamically from the returned data instead of hardcoding the count, removing the NotSupportedException entirely."],"exampleFix":"// before\nif (siloData.Count > 5)\n{\n    throw new NotSupportedException(\"The frontend cant support more than 6 silos\");\n}\nreturn Ok(siloData);\n\n// after (build chart series dynamically client-side)\nreturn Ok(siloData);","handlingStrategy":"validation","validationCode":"// Caller / test harness: check silo count before relying on the endpoint\nvar stats = await clusterClient.GetGrain<IManagementGrain>(0).GetDetailedGrainStatistics();\nvar siloCount = stats.Select(s => s.SiloAddress).Distinct().Count();\nif (siloCount > 5) { /* scale down or extend frontend before calling /api/stats/silos */ }","typeGuard":null,"tryCatchPattern":"// Frontend JS — degrade gracefully instead of breaking the chart on a 500\nfetch('/api/stats/silos')\n  .then(r => r.ok ? r.json() : Promise.reject(new Error(`status ${r.status}`)))\n  .then(updateChart)\n  .catch(err => { console.warn('Stats unavailable, keeping last chart', err); });","preventionTips":["Run the ActivationRebalancing playground with the documented number of silos (4-5).","Make the frontend chart build series dynamically so it adapts to any silo count.","Remove the hard-coded > 5 cap or raise it to match the number of chart series you support."],"tags":["orleans","playground","ui-limit","managementgrain","argument-validation"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}