← back to Exo
UNKNOWN to PREPARING (#1112)
59e7594e3412a3164caa7de5d92416ec542fd67a · 2026-01-09 16:46:51 +0500 · Sami Khan
## Motivation
The "UNKNOWN" status shown when first launching an instance is confusing
and unhelpful. "PREPARING" better describes what's actually happening.

## Changes
- Renamed status from "UNKNOWN" to "PREPARING" in dashboard
(+page.svelte)
- Renamed unknown state to preparing in macOS app
(InstanceViewModel.swift, InstanceRowView.swift)
## Why It Works
The status appears when an instance exists but runners haven't reported
status yet. "PREPARING" accurately describes this transitional state.
## Test Plan
### Manual Testing
Hardware: MacBook Pro
<img width="319" height="200" alt="image"
src="https://github.com/user-attachments/assets/9a1c3caf-026d-47ea-80d1-63c6e41d93aa"
/>
### Automated Testing
N/A
Files touched
M app/EXO/EXO/ViewModels/InstanceViewModel.swiftM app/EXO/EXO/Views/InstanceRowView.swiftM dashboard/src/routes/+page.svelte
Diff
commit 59e7594e3412a3164caa7de5d92416ec542fd67a
Author: Sami Khan <98742866+samiamjidkhan@users.noreply.github.com>
Date: Fri Jan 9 16:46:51 2026 +0500
UNKNOWN to PREPARING (#1112)
## Motivation
The "UNKNOWN" status shown when first launching an instance is confusing
and unhelpful. "PREPARING" better describes what's actually happening.

## Changes
- Renamed status from "UNKNOWN" to "PREPARING" in dashboard
(+page.svelte)
- Renamed unknown state to preparing in macOS app
(InstanceViewModel.swift, InstanceRowView.swift)
## Why It Works
The status appears when an instance exists but runners haven't reported
status yet. "PREPARING" accurately describes this transitional state.
## Test Plan
### Manual Testing
Hardware: MacBook Pro
<img width="319" height="200" alt="image"
src="https://github.com/user-attachments/assets/9a1c3caf-026d-47ea-80d1-63c6e41d93aa"
/>
### Automated Testing
N/A
---
app/EXO/EXO/ViewModels/InstanceViewModel.swift | 6 +++---
app/EXO/EXO/Views/InstanceRowView.swift | 2 +-
dashboard/src/routes/+page.svelte | 6 +++---
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/app/EXO/EXO/ViewModels/InstanceViewModel.swift b/app/EXO/EXO/ViewModels/InstanceViewModel.swift
index 510e85fe..17b694ec 100644
--- a/app/EXO/EXO/ViewModels/InstanceViewModel.swift
+++ b/app/EXO/EXO/ViewModels/InstanceViewModel.swift
@@ -57,7 +57,7 @@ struct InstanceViewModel: Identifiable, Equatable {
case waiting
case failed
case idle
- case unknown
+ case preparing
var label: String {
switch self {
@@ -68,7 +68,7 @@ struct InstanceViewModel: Identifiable, Equatable {
case .waiting: return "Waiting"
case .failed: return "Failed"
case .idle: return "Idle"
- case .unknown: return "Unknown"
+ case .preparing: return "Preparing"
}
}
}
@@ -185,7 +185,7 @@ extension InstanceViewModel.State {
} else if statuses.isEmpty {
self = .idle
} else {
- self = .unknown
+ self = .preparing
}
}
}
diff --git a/app/EXO/EXO/Views/InstanceRowView.swift b/app/EXO/EXO/Views/InstanceRowView.swift
index 64e61ea2..6c5502b1 100644
--- a/app/EXO/EXO/Views/InstanceRowView.swift
+++ b/app/EXO/EXO/Views/InstanceRowView.swift
@@ -83,7 +83,7 @@ struct InstanceRowView: View {
case .ready: return .teal
case .waiting, .idle: return .gray
case .failed: return .red
- case .unknown: return .secondary
+ case .preparing: return .secondary
}
}
diff --git a/dashboard/src/routes/+page.svelte b/dashboard/src/routes/+page.svelte
index abc603ff..a196c72c 100644
--- a/dashboard/src/routes/+page.svelte
+++ b/dashboard/src/routes/+page.svelte
@@ -593,7 +593,7 @@ function toggleInstanceDownloadDetails(nodeId: string): void {
// Unwrap the instance
const [instanceTag, instance] = getTagged(instanceWrapped);
if (!instance || typeof instance !== 'object') {
- return { isDownloading: false, progress: null, statusText: 'UNKNOWN', perNode: [] };
+ return { isDownloading: false, progress: null, statusText: 'PREPARING', perNode: [] };
}
const inst = instance as { shardAssignments?: { nodeToRunner?: Record<string, string>; runnerToShard?: Record<string, unknown>; modelId?: string } };
@@ -706,7 +706,7 @@ function toggleInstanceDownloadDetails(nodeId: string): void {
function deriveInstanceStatus(instanceWrapped: unknown): { statusText: string; statusClass: string } {
const [, instance] = getTagged(instanceWrapped);
if (!instance || typeof instance !== 'object') {
- return { statusText: 'UNKNOWN', statusClass: 'inactive' };
+ return { statusText: 'PREPARING', statusClass: 'inactive' };
}
const inst = instance as { shardAssignments?: { runnerToShard?: Record<string, unknown> } };
@@ -735,7 +735,7 @@ function toggleInstanceDownloadDetails(nodeId: string): void {
const has = (s: string) => statuses.includes(s);
- if (statuses.length === 0) return { statusText: 'UNKNOWN', statusClass: 'inactive' };
+ if (statuses.length === 0) return { statusText: 'PREPARING', statusClass: 'inactive' };
if (has('Failed')) return { statusText: 'FAILED', statusClass: 'failed' };
if (has('Shutdown')) return { statusText: 'SHUTDOWN', statusClass: 'inactive' };
if (has('Loading')) return { statusText: 'LOADING', statusClass: 'starting' };
← c65320ac Fix mlx seed (#1094)
·
back to Exo
·
scrollbars fixed (#1113) d1e88def →