farion1231/cc-switch · warning · PiFormValidationError

Model {{index}} needs a display name

Error message

Model {{index}} needs a display name

What it means

After id checks, PiProviderForm validates each model's display name: it trims model.name and throws pi.form.modelNameRequired (1-based index, focusing #pi-model-name-<rowKey>) when includeName is true and the trimmed name is empty. includeName is always true on create (!isEdit) but on edit it is only true when model.hasName is set — i.e. when the row actually carries a name property — so imported/partial models without a name stay legal in edit mode.

Source

Thrown at src/components/providers/forms/PiProviderForm.tsx:1132

            true,
          );
        }
        if (seen.has(id)) {
          throw new PiFormValidationError(
            t("pi.form.duplicateModel", { id }),
            `#pi-model-id-${model.key}`,
            true,
          );
        }
        seen.add(id);
        const displayName = model.name.trim();
        const includeName = !isEdit || model.hasName;
        const includeReasoning = !isEdit || model.hasReasoning;
        const includeInput = !isEdit || model.hasInput;
        const includeContextWindow = !isEdit || model.hasContextWindow;
        const includeMaxTokens = !isEdit || model.hasMaxTokens;
        if (includeName && !displayName) {
          throw new PiFormValidationError(
            t("pi.form.modelNameRequired", { index: index + 1 }),
            `#pi-model-name-${model.key}`,
            true,
          );
        }
        const contextWindow = includeContextWindow
          ? positiveNumber(
              model.contextWindow,
              t("pi.form.positiveNumberRequired", {
                label: t("pi.form.contextWindow"),
              }),
              `#pi-model-context-window-${model.key}`,
            )
          : undefined;
        const maxTokens = includeMaxTokens
          ? positiveNumber(
              model.maxTokens,
              t("pi.form.positiveNumberRequired", {

View on GitHub (pinned to 0b5da51016)

Solutions

  1. Enter a human-readable display name for the row indicated by {index} (trim happens automatically).
  2. On edit of an imported model that legitimately has no name, clear it fully rather than leaving spaces — or leave the row untouched so hasName logic keeps it optional.
  3. For bulk imports, default name to the model id when the source has no title.

Example fix

// before
const models = [{ key: "m1", id: "kimi-k2", name: "   " }];
submit(identity); // throws 'Model 1 needs a display name'

// after
const models = [{ key: "m1", id: "kimi-k2", name: "Kimi K2" }];
submit(identity);
Defensive patterns

Strategy: validation

Validate before calling

const badName = models.findIndex((m) => (!isEdit || m.hasName) && m.name.trim().length === 0);
if (badName >= 0) focusRow(`#pi-model-name-${models[badName].key}`);

Try / catch

catch (e) {
  if (e instanceof PiFormValidationError) { setFormError(e.message); document.querySelector(e.fieldSelector ?? "")?.focus(); return; }
  throw e;
}

Prevention

When it happens

Trigger: Create mode: any model row with an empty or whitespace-only display name. Edit mode: only rows whose stored data includes a name (hasName) but whose name field was cleared to whitespace.

Common situations: Users fill the id and skip the optional-looking name; import produces name: "" rows that then get edited; whitespace pasted into the name input.

Related errors


AI-assisted analysis of farion1231/cc-switch@0b5da51016 (2026-08-20). Data as JSON: /api/errors/bb78aa8adca82a48. Report an issue: GitHub.