Skip to content

desktop: validate backend and relay URLs in settings#326

Merged
ericflo merged 1 commit intomainfrom
feat/backend-url-validation
Apr 20, 2026
Merged

desktop: validate backend and relay URLs in settings#326
ericflo merged 1 commit intomainfrom
feat/backend-url-validation

Conversation

@ericflo
Copy link
Copy Markdown
Owner

@ericflo ericflo commented Apr 20, 2026

What

Validate backend_url and relay_url in the desktop app at two layers so a bad value can't slip through to the worker loop.

  • Rust (WorkerManager::save_settings) — parse with url::Url::parse and reject empty strings, non-http(s) schemes, and missing hosts before persisting settings.json.
  • UI (ui/index.html) — live validation in the settings form and onboarding wizard using new URL(), with inline per-field error text. Wizard refuses to advance past a bad backend URL at step 0 or a bad relay URL at step 1.
  • Hints now name the three common local backends (Ollama 11434, LM Studio 1234, Kiln 8420) so the field is self-documenting.

Why

Scoping notes: the backend URL field itself already exists in both the settings tab and the onboarding wizard — it's an AppSettings field (default http://localhost:11434), surfaces in the UI, is wired to WorkerDaemonConfig.backend_base_url, and hot-reloads a running worker on save. The one real gap from the task checklist was URL validation: a user could type localhost:11434 (no scheme), foo bar, or leave the field blank and hit Save without any feedback. Bad values then surfaced as opaque reqwest errors in the worker loop.

Tests

Added 11 unit tests in crates/modelrelay-desktop/src/lib.rs covering:

  • Accept: Ollama default, LM Studio default, Kiln default, remote HTTPS host, IP+path
  • Reject: empty, whitespace-only, missing scheme, garbage, ftp:// scheme, http://:8080/path (empty host)

The validation logic was exercised locally in a scratch crate (all 11 tests green) — Cloud Eric can't run cargo check/clippy on the desktop crate directly because the sandbox lacks GTK/webkit2gtk system libs, so CI on a Linux runner is the first end-to-end build. cargo fmt --check -p modelrelay-desktop passes.

Release

No release tooling change needed — desktop builds are cut by pushing a desktop-v* tag, which triggers the existing tauri-action workflow. Not doing that here; a new desktop build can be cut separately once this lands.

Both URLs were persisted as free-form strings. An invalid host or
missing scheme fell through to the worker loop as a confusing runtime
error. Validate at two layers:

- Rust: reject empty, non-http/https, and hostless URLs in
  WorkerManager::save_settings before persist (url::Url::parse).
- UI: live validation in the settings form and onboarding wizard using
  new URL(), with inline per-field error messages.

Hints now name the common local backends (Ollama 11434, LM Studio 1234,
Kiln 8420) so the field is self-documenting. 11 unit tests cover the
accept and reject cases, including the three default ports and an
http://:port/path hostless case.
@ericflo ericflo merged commit 95b3fb9 into main Apr 20, 2026
12 checks passed
@ericflo ericflo deleted the feat/backend-url-validation branch April 20, 2026 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant