farion1231/cc-switch · error · PiFormValidationError

Configuration must be a JSON object, not an array or other t

Error message

Configuration must be a JSON object, not an array or other type

What it means

PiProviderForm validates the 'settingsConfig' advanced JSON editor with parseJsonObject() before saving a Pi provider. If the text does not parse to a plain JSON object (it is an array, string, number, boolean, null, or syntactically invalid), submit() throws PiFormValidationError with jsonEditor.mustBeObject and focuses the element with id #pi-settings-config. Pi merges this object into its provider settings file, so a non-object top level would corrupt the config.

Source

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

      setProviderCompat(value);
    },
    [updateSettingsConfig],
  );

  const handleProviderKeyChange = useCallback((value: string) => {
    const normalized = value.toLowerCase().replace(/[^a-z0-9-]/g, "");
    setProviderKey(normalized);
  }, []);

  const submit = async (identity: ProviderFormData) => {
    onSubmittingChange?.(true);
    setFormError(null);
    try {
      if (!isEdit && selectedPresetId === null) {
        throw new PiFormValidationError(t("pi.form.selectPresetRequired"));
      }
      if (!parseJsonObject(identity.settingsConfig)) {
        throw new PiFormValidationError(
          t("jsonEditor.mustBeObject"),
          "#pi-settings-config",
        );
      }
      const trimmedName = identity.name.trim();
      const trimmedKey = providerKey.trim();
      if (!trimmedName) {
        throw new PiFormValidationError(
          t("pi.form.nameRequired"),
          'input[name="name"]',
        );
      }
      if (!isEdit && !trimmedKey) {
        throw new PiFormValidationError(
          t("pi.form.providerKeyRequired"),
          "#pi-provider-key",
        );
      }

View on GitHub (pinned to 0b5da51016)

Solutions

  1. Make the editor content a single JSON object at the top level, e.g. '{ "header": { ... } }' instead of '[ ... ]'.
  2. Run the text through JSON.parse in the console/devtools to find syntax errors, fix them, and resubmit.
  3. If you meant to keep a list, nest it one level down as a named property of the root object.

Example fix

// before
settingsConfig = "[{ \"x\": 1 }]"; // array at top level -> throws

// after
settingsConfig = "{ \"items\": [{ \"x\": 1 }] }"; // object at top level
Defensive patterns

Strategy: validation

Validate before calling

function isJsonObjectText(text: string): boolean {
  try {
    return JSON.parse(text) !== null && typeof JSON.parse(text) === "object" && !Array.isArray(JSON.parse(text));
  } catch {
    return false;
  }
}
// before submit:
if (!isJsonObjectText(settingsConfig)) setEditorError("Top level must be a JSON object");

Type guard

function isPlainObject(v: unknown): v is Record<string, unknown> {
  return typeof v === "object" && v !== null && !Array.isArray(v);
}

Try / catch

catch (e) {
  if (e instanceof PiFormValidationError) { setFormError(e.message); document.querySelector("#pi-settings-config")?.focus(); return; }
  throw e;
}

Prevention

When it happens

Trigger: Entering e.g. '[]', '"custom"', '123', or unbalanced JSON in the settings configuration editor and submitting; pasting a settings snippet that is a JSON array of objects instead of a single object.

Common situations: Copying a fragment from pi's settings.json that is an array-valued entry; leaving stray commas/quotes after hand-editing; wrapping config in brackets '[{...}]' out of habit.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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