farion1231/cc-switch · warning · PiFormValidationError

pi.form.thinkingLevelMapInvalid

Error message

pi.form.thinkingLevelMapInvalid

What it means

Thrown per-model in PiProviderForm's submit() when the row has a thinking-level map enabled (model.hasThinkingLevelMap) but its value fails isPiThinkingLevelMap (src/config/piThinkingProfiles.ts:347-355): the value must be a plain object whose keys are among 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max' and whose values are strings or null. Arrays, unknown level keys, or numeric/boolean values fail. fieldSelector '#pi-model-thinking-levels-{model.key}' with revealAdvanced=true expands the row, opens the thinking map editor, and focuses it (PiProviderForm.tsx:1262-1277).

Source

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

                label: t("pi.form.contextWindow"),
              }),
              `#pi-model-context-window-${model.key}`,
            )
          : undefined;
        const maxTokens = includeMaxTokens
          ? positiveNumber(
              model.maxTokens,
              t("pi.form.positiveNumberRequired", {
                label: t("pi.form.maxTokens"),
              }),
              `#pi-model-max-tokens-${model.key}`,
            )
          : undefined;
        if (
          model.hasThinkingLevelMap &&
          !isPiThinkingLevelMap(model.thinkingLevelMap)
        ) {
          throw new PiFormValidationError(
            t("pi.form.thinkingLevelMapInvalid"),
            `#pi-model-thinking-levels-${model.key}`,
            true,
          );
        }
        // Pi's schema supports rare per-model api/baseUrl overrides. Keep
        // imported values losslessly, but use the provider-level format and
        // endpoint as the normal product model.
        const modelApi =
          typeof model.passthrough.api === "string"
            ? model.passthrough.api.trim()
            : "";
        const modelBaseUrl =
          typeof model.passthrough.baseUrl === "string"
            ? model.passthrough.baseUrl.trim()
            : "";
        // Existing explicit nodes may be partial overrides of a Pi built-in
        // provider. Pi inherits the built-in transport in that case, so only

View on GitHub (pinned to a2e22f3302)

Solutions

  1. Correct the map so every key is one of off/minimal/low/medium/high/xhigh/max and every value is a string or null
  2. If the row should not override thinking levels, remove the thinking map entirely instead of leaving an invalid one
  3. Validate with isPiThinkingLevelMap live as the user types and disable Save on failure

Example fix

// before
thinkingLevelMap: { high: 1, ultra: "model-x" }

// after
thinkingLevelMap: { high: "model-x-thinking", medium: null }
Defensive patterns

Strategy: type-guard

Validate before calling

import { isPiThinkingLevelMap } from "@/config/piThinkingProfiles";
for (const m of models) {
  if (m.hasThinkingLevelMap && !isPiThinkingLevelMap(m.thinkingLevelMap)) {
    setFormError(t("pi.form.thinkingLevelMapInvalid"));
    return;
  }
}

Type guard

import { isPiThinkingLevelMap } from "@/config/piThinkingProfiles";
// isPiThinkingLevelMap(value: unknown): value is PiThinkingLevelMap
// — plain object, keys in {off, minimal, low, medium, high, xhigh, max}, values string | null

Try / catch

try {
  await submit(identity);
} catch (error) {
  if (error instanceof Error && error.name === "PiFormValidationError") { /* the form expands the row AND its thinking-map editor via '#pi-model-thinking-levels-{key}' */ return; }
  throw error;
}

Prevention

When it happens

Trigger: Hand-editing the thinking map JSON with a typo'd level like 'ultra' or 'x-high'; using numbers ('high': 1) instead of model-name strings or null; leaving a JSON array or nested object in the field; importing a config with an off-spec thinking map.

Common situations: Copying thinking configs from other tools whose level names differ; assuming an empty object is fine for 'explicitly no mapping'; version drift when PI_THINKING_LEVELS gains/renames levels between releases.

Related errors


AI-assisted analysis of farion1231/cc-switch@a2e22f3302 (2026-08-16). Data as JSON: /api/errors/138209de1a2f13cb. Report an issue: GitHub.