{"record":{"id":"7a9dbb490a32620f","repo":"farion1231/cc-switch","slug":"thinking-levels-may-only-use-pi-s-native-keys-wit","errorCode":null,"errorMessage":"Thinking levels may only use Pi's native keys, with string or null values.","messagePattern":"Thinking levels may only use Pi's native keys, with string or null values\\.","errorType":"validation","errorClass":"PiFormValidationError","httpStatus":null,"severity":"error","filePath":"src/components/providers/forms/PiProviderForm.tsx","lineNumber":1160,"sourceCode":"                label: t(\"pi.form.contextWindow\"),\n              }),\n              `#pi-model-context-window-${model.key}`,\n            )\n          : undefined;\n        const maxTokens = includeMaxTokens\n          ? positiveNumber(\n              model.maxTokens,\n              t(\"pi.form.positiveNumberRequired\", {\n                label: t(\"pi.form.maxTokens\"),\n              }),\n              `#pi-model-max-tokens-${model.key}`,\n            )\n          : undefined;\n        if (\n          model.hasThinkingLevelMap &&\n          !isPiThinkingLevelMap(model.thinkingLevelMap)\n        ) {\n          throw new PiFormValidationError(\n            t(\"pi.form.thinkingLevelMapInvalid\"),\n            `#pi-model-thinking-levels-${model.key}`,\n            true,\n          );\n        }\n        // Pi's schema supports rare per-model api/baseUrl overrides. Keep\n        // imported values losslessly, but use the provider-level format and\n        // endpoint as the normal product model.\n        const modelApi =\n          typeof model.passthrough.api === \"string\"\n            ? model.passthrough.api.trim()\n            : \"\";\n        const modelBaseUrl =\n          typeof model.passthrough.baseUrl === \"string\"\n            ? model.passthrough.baseUrl.trim()\n            : \"\";\n        // Existing explicit nodes may be partial overrides of a Pi built-in\n        // provider. Pi inherits the built-in transport in that case, so only","sourceCodeStart":1142,"sourceCodeEnd":1178,"githubUrl":"https://github.com/farion1231/cc-switch/blob/0b5da510168914b251481654a568c3ffacd62cf4/src/components/providers/forms/PiProviderForm.tsx#L1142-L1178","documentation":"PiProviderForm validates the per-model thinking-level map with isPiThinkingLevelMap() when the row carries one (model.hasThinkingLevelMap); on failure it throws pi.form.thinkingLevelMapInvalid focusing #pi-model-thinking-levels-<rowKey> with revealAdvanced. Pi's native schema only accepts its own thinking-level keys mapped to string or null values (e.g. levels like 'high'/'medium'/'off' style names), so free-form objects, numbers, booleans, or arrays are rejected to keep the generated settings file schema-valid.","triggerScenarios":"Hand-editing the thinking levels JSON to use non-native keys (custom names like \"deep-think\"), values of wrong type (0/1/2, true, nested objects), or pasting a generic reasoning-effort config from another tool; only checked when the row actually has a thinkingLevelMap.","commonSituations":"Porting OpenAI-style reasoning_effort numbers or Anthropic budget_tokens into Pi's thinking map; typos in level keys; mixing formats when copying configs between providers.","solutions":["Rewrite the map to use Pi's native thinking-level keys with string or null values, e.g. { \"default\": \"high\", \"off\": null }-shaped entries per Pi's documented schema.","Remove the thinking-level override entirely if you do not need it — the field is optional (hasThinkingLevelMap false rows skip validation).","Check Pi's provider schema/docs for the exact allowed key set for your provider version before hand-writing the map."],"exampleFix":"// before\nthinkingLevelMap = { high: 3, medium: 2 }; // numeric values -> throws\n// or\nthinkingLevelMap = { \"deep-think\": \"on\" }; // non-native key -> throws\n\n// after\nthinkingLevelMap = { high: \"high\", medium: \"medium\", low: null }; // string|null values on native keys","handlingStrategy":"type-guard","validationCode":"import { isPiThinkingLevelMap } from \"./piSchema\"; // same helper the form uses\nif (model.hasThinkingLevelMap && !isPiThinkingLevelMap(model.thinkingLevelMap)) {\n  showEditorError(\"Thinking levels: native keys only, string or null values\");\n}","typeGuard":"function isPiThinkingLevelMap(v: unknown): v is Record<string, string | null> {\n  if (typeof v !== \"object\" || v === null || Array.isArray(v)) return false;\n  return Object.values(v).every((x) => x === null || typeof x === \"string\");\n}","tryCatchPattern":"catch (e) {\n  if (e instanceof PiFormValidationError) { setAdvancedOpen(true); setFormError(e.message); return; }\n  throw e;\n}","preventionTips":["Offer a dropdown of Pi's documented thinking-level keys instead of free-text JSON.","Validate the map on change and block saving while invalid."],"tags":["pi","form-validation","thinking-levels","schema-validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"0b5da510168914b251481654a568c3ffacd62cf4","analyzedAt":"2026-08-20T14:29:00.113Z","contentChangedAt":"2026-08-20T14:29:00.113Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}