Repository navigation
fix: warn user when no models to migrate during storage change - #433
Conversation
When user attempts to change model storage location with no models downloaded, the migration API returns moved=0 early. Previously the UI would still call setCustomModelsDir() and restart the server, causing unexpected behavior (hang/connection lost). This change checks migrationResult.moved === 0 and shows a helpful toast message instead of proceeding with the storage change. Fixes: jamiepine#426
ð WalkthroughWalkthroughThe migration flow in ModelManagement.tsx now captures the result of Changes
Estimated code review effortðŊ 2 (Simple) | âąïļ ~10 minutes Poem
ðĨ Pre-merge checks | â 4 | â 1â Failed checks (1 warning)
â Passed checks (4 passed)
âïļ Tip: You can configure your own custom pre-merge checks in the settings. âĻ Finishing Touchesð§Š Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
ðĪ Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/components/ServerSettings/ModelManagement.tsx`:
- Around line 980-983: The code reads migrationResult.moved but
apiClient.migrateModels is typed as returning Promise<{ source: string;
destination: string }>, causing a type mismatch; update the migrateModels return
type in the API client to include the moved property (e.g., add moved: number or
moved?: number to the returned object type or shared response interface used by
migrateModels), adjust any related type alias or interface declarations used by
apiClient.migrateModels to reflect this field, and then rebuild/TypeScript-check
to ensure all call sites (including the check using migrationResult.moved)
compile correctly.
ðŠ Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
âđïļ Review info
âïļ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6f9e0a9a-ad9a-4255-8d6e-5e16de071281
ð Files selected for processing (1)
app/src/components/ServerSettings/ModelManagement.tsx
| const migrationResult = await apiClient.migrateModels(newDir); | ||
|
|
||
| // If no models to migrate, warn user and skip the change | ||
| if (migrationResult.moved === 0) { |
There was a problem hiding this comment.
ð§Đ Analysis chain
ð Script executed:
#!/bin/bash
set -euo pipefail
echo "1) Locate migrateModels definitions and callsites"
rg -n --type=ts --type=tsx -C2 '\bmigrateModels\s*\('
echo
echo "2) Check declared response type for apiClient.migrateModels"
rg -n --type=ts -C3 'async\s+migrateModels\s*\(destination:\s*string\)\s*:\s*Promise<\{[^}]*\}>' app/src/lib/api/client.ts
echo
echo "3) Find usage of `moved` to confirm contract expectations"
rg -n --type=ts --type=tsx -C2 '\bmoved\b'Repository: jamiepine/voicebox
Length of output: 156
ð Script executed:
#!/bin/bash
set -euo pipefail
echo "=== 1) Search for migrateModels definitions and callsites ==="
rg -n 'migrateModels\s*\(' --type ts -A5 -B2
echo
echo "=== 2) Check app/src/lib/api/client.ts for migrateModels ==="
if [ -f app/src/lib/api/client.ts ]; then
cat -n app/src/lib/api/client.ts | head -100
fi
echo
echo "=== 3) Check ModelManagement.tsx around lines 980-983 ==="
if [ -f app/src/components/ServerSettings/ModelManagement.tsx ]; then
sed -n '975,990p' app/src/components/ServerSettings/ModelManagement.tsx | cat -n
fi
echo
echo "=== 4) Find all uses of .moved property ==="
rg -n '\.moved' --type ts -B3 -A2Repository: jamiepine/voicebox
Length of output: 6464
ð Script executed:
#!/bin/bash
set -euo pipefail
echo "=== 1) Search for migration-related types ==="
rg -n -i 'migrate|migration' app/src/lib/api/types.ts -B2 -A5
echo
echo "=== 2) Search for MigrateModels or similar types ==="
rg -n 'type.*Migrate|interface.*Migrate' app/src/lib/api/
echo
echo "=== 3) Check if moved field exists anywhere ==="
rg -n 'moved\s*:' app/src/lib/api/
echo
echo "=== 4) Check context around the migration response usage ==="
sed -n '980,1010p' app/src/components/ServerSettings/ModelManagement.tsx | cat -nRepository: jamiepine/voicebox
Length of output: 107
ð Script executed:
#!/bin/bash
set -euo pipefail
echo "=== 1) Check if types.ts exists and list files in api ==="
ls -la app/src/lib/api/
echo
echo "=== 2) Broader search for 'moved' anywhere in the codebase ==="
rg -n 'moved' --type ts --max-count 10
echo
echo "=== 3) Full context around the migration code (wider range) ==="
sed -n '970,1010p' app/src/components/ServerSettings/ModelManagement.tsx | cat -n
echo
echo "=== 4) Search in server backend for migration response ==="
find . -name '*.py' -o -name '*.ts' | xargs grep -l 'models/migrate' 2>/dev/null | head -5Repository: jamiepine/voicebox
Length of output: 4452
ð Script executed:
#!/bin/bash
set -euo pipefail
echo "=== 1) Search for /models/migrate endpoint in backend ==="
rg -n 'models/migrate|def.*migrate' backend/routes/models.py -B5 -A20
echo
echo "=== 2) Check if there's a migration response type/model ==="
rg -n 'class.*Migrate|def.*migrate' backend/ -B2 -A10
echo
echo "=== 3) Look for the response structure with moved field ==="
rg -n '"moved"|\.moved' backend/ -B3 -A3Repository: jamiepine/voicebox
Length of output: 11983
migrationResult.moved is not in the declared API type (build-break risk).
At Line 983, you access migrationResult.moved, but apiClient.migrateModels() is typed as Promise<{ source: string; destination: string }> in app/src/lib/api/client.ts:387. This is a TypeScript contract mismatch.
The backend does return moved when no models are found (see backend/routes/models.py:140), but the API client type doesn't declare it, causing a type error.
Update the API client response type to include the moved field:
Suggested fix
-async migrateModels(destination: string): Promise<{ source: string; destination: string }> {
+async migrateModels(destination: string): Promise<{ source: string; destination: string; moved: number; errors?: unknown[] }> {
return this.request('/models/migrate', {
method: 'POST',
body: JSON.stringify({ destination }),
});
}ðĪ Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/src/components/ServerSettings/ModelManagement.tsx` around lines 980 -
983, The code reads migrationResult.moved but apiClient.migrateModels is typed
as returning Promise<{ source: string; destination: string }>, causing a type
mismatch; update the migrateModels return type in the API client to include the
moved property (e.g., add moved: number or moved?: number to the returned object
type or shared response interface used by migrateModels), adjust any related
type alias or interface declarations used by apiClient.migrateModels to reflect
this field, and then rebuild/TypeScript-check to ensure all call sites
(including the check using migrationResult.moved) compile correctly.
ModelManagement.tsx reads migrationResult.moved (added in #433) but apiClient.migrateModels() was typed as returning only { source, destination }. The backend actually returns { moved: int, errors: list[str], source, destination } (backend/routes/models.py:140, 168). Widen the TS return type so the check typechecks under the new CI gate from #418. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
#470) ModelManagement.tsx reads migrationResult.moved (added in #433) but apiClient.migrateModels() was typed as returning only { source, destination }. The backend actually returns { moved: int, errors: list[str], source, destination } (backend/routes/models.py:140, 168). Widen the TS return type so the check typechecks under the new CI gate from #418. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
When user attempts to change model storage location with no models downloaded, the migration API returns
moved: 0early. Previously the UI would still callsetCustomModelsDir()and restart the server, causing unexpected behavior (hang/connection lost) as described in issue #426.This fix checks
migrationResult.moved === 0and shows a helpful toast message instructing the user to download at least one model before changing the storage location, instead of proceeding with a no-op storage change.Test plan
Related issue
Fixes #426
Summary by CodeRabbit