Hmbown/CodeWhale · error

Choose both a provider and a model.

Error message

Choose both a provider and a model.

What it means

buildCreateThreadRequest validates that both a provider id and a model name are present before constructing the create-thread request body. An empty/whitespace providerId or model means the Runtime could not select a model, so it throws.

Solutions

  1. Wait for the provider/model catalog to load and ensure both selectors have values before creating a thread.
  2. Preselect a default provider/model once the catalog arrives.
  3. Check why the model list is empty for the chosen provider (provider down or misconfigured).

Example fix

// before
const req = buildCreateThreadRequest(providerSel.value, modelSel.value);
// after
if (!providerSel.value || !modelSel.value) { showHint('Pick a provider and model'); return; }
const req = buildCreateThreadRequest(providerSel.value, modelSel.value);
Defensive patterns

Strategy: validation

Validate before calling

if (!providerSel.value.trim() || !modelSel.value.trim()) {
  showHint('Choose a provider and a model');
  return;
}

Type guard

function hasModelChoice(provider, model) {
  return String(provider || '').trim().length > 0 && String(model || '').trim().length > 0;
}

Try / catch

try {
  const req = buildCreateThreadRequest(provider, model);
} catch (e) {
  showHint(e.message);
  return;
}

Prevention

When it happens

Trigger: Calling buildCreateThreadRequest('', ...) or with an empty model; provider/model selectors not yet populated (catalog load failed or still loading) when thread creation is triggered.

Common situations: User clicks "new thread" before the provider/model dropdowns finish loading; a provider was chosen but no model selected; a config default provider is missing so nothing is preselected.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/a5c7656996d9ba1b. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/runtime_web/app.mjs:576

export function modelOptionLabel(model) {
  const id = String(model?.id || "").trim();
  return model?.image_input === "supported" ? `${id} · Vision` : id;
}

export function providerOptionLabel(provider) {
  const id = String(provider?.id || "").trim();
  const displayName = String(provider?.display_name || id).trim();
  const exactId = String(provider?.model_provider_id || "").trim();
  return exactId && exactId !== id ? `${displayName} · ${exactId}` : displayName;
}

export function buildCreateThreadRequest(providerId, model, modelProviderId = "") {
  const modelProvider = String(providerId || "").trim();
  const exactProviderId = String(modelProviderId || "").trim();
  const selectedModel = String(model || "").trim();
  if (!modelProvider || !selectedModel) {
    throw new Error("Choose both a provider and a model.");
  }
  const request = { model_provider: modelProvider, model: selectedModel };
  if (exactProviderId) request.model_provider_id = exactProviderId;
  return request;
}

export function threadProviderLabel(thread) {
  const exact = String(thread?.model_provider_id || "").trim();
  const generic = String(thread?.model_provider || "").trim();
  return exact || generic;
}

export function claimInFlight(inFlight, key) {
  const action = String(key || "").trim();
  if (!(inFlight instanceof Set) || !action || inFlight.has(action)) return false;
  inFlight.add(action);
  return true;
}

View on GitHub (pinned to 73e0f67d83)