microsoft/aspire · error · InvalidOperationException
Historical dashboard data is read-only.
Error message
Historical dashboard data is read-only.
What it means
SelectedDashboardClient wraps the live dashboard backend; when the session is in read-only (historical) mode, mutating operations must not run. EnsureWritable is called by mutating APIs (ClearConsoleLogsAsync, SendInteractionRequestAsync, ExecuteResourceCommandAsync, UploadFileAsync) and throws this InvalidOperationException when IsReadOnly is true. Historical data views are intentionally immutable.
Solutions
- Check IsReadOnly before issuing any mutating call and no-op or prompt the user instead
- Reconnect the dashboard client to a live session to perform commands or uploads
- Restrict mutation entry points in UI so they are disabled in historical mode
Example fix
// before
await client.ExecuteResourceCommandAsync(command);
// after
if (!client.IsReadOnly)
{
await client.ExecuteResourceCommandAsync(command);
} Defensive patterns
Strategy: validation
Validate before calling
if (client.IsReadOnly)
{
return; // historical sessions are immutable
} Try / catch
try { await client.ExecuteResourceCommandAsync(cmd); }
catch (InvalidOperationException ex) when (ex.Message.Contains("read-only"))
{
logger.LogWarning("Cannot mutate historical dashboard data");
} Prevention
- Gate all mutating calls behind an IsReadOnly check
- Disable command/upload UI affordances in historical mode
- Reconnect to a live session to run commands
When it happens
Trigger: Calling ExecuteResourceCommandAsync, ClearConsoleLogsAsync, SendInteractionRequestAsync, or UploadFileAsync on a SelectedDashboardClient whose session targets historical/archived data (IsReadOnly == true).
Common situations: Dashboard tooling or extensions operating against a historical data view (e.g. viewing archived logs from a previous session) and invoking commands or uploads that only make sense on a live session.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Historical dashboard data is read-only.
- AppHost:ResourceService:ApiKey is not specified in…
- [aspire-terminal] WS closed abnormally
- Azure provisioning options were not provided.
- Dashboard API returned unexpected content type
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/e47d8594a70fc39d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Dashboard/ServiceClient/SelectedDashboardClient.cs:77
}
public Task<ResourceCommandResponseViewModel> ExecuteResourceCommandAsync(string resourceName, string resourceType, CommandViewModel command, ExecuteResourceCommandOptions options, CancellationToken cancellationToken)
{
EnsureWritable();
return currentClient.ExecuteResourceCommandAsync(resourceName, resourceType, command, options, cancellationToken);
}
public Task<string> UploadFileAsync(Stream fileStream, string fileName, long expectedSize, int interactionId, string inputName, CancellationToken cancellationToken)
{
EnsureWritable();
return currentClient.UploadFileAsync(fileStream, fileName, expectedSize, interactionId, inputName, cancellationToken);
}
private void EnsureWritable()
{
if (IsReadOnly)
{
throw new InvalidOperationException("Historical dashboard data is read-only.");
}
}
private static async IAsyncEnumerable<WatchInteractionsResponseUpdate> EmptyInteractionsAsync()
{
await Task.CompletedTask.ConfigureAwait(false);
yield break;
}
public ValueTask DisposeAsync() => ValueTask.CompletedTask;
}View on GitHub (pinned to 25830f84bd)