farion1231/cc-switch · warning · PiFormValidationError

jsonEditor.mustBeObject

Error message

jsonEditor.mustBeObject

What it means

Thrown by PiProviderForm's submit() when identity.settingsConfig fails parseJsonObject() (PiProviderForm.tsx:157-166): the text must JSON.parse successfully AND the top-level value must be a non-null, non-array object. Arrays, strings, numbers, booleans, and malformed JSON (trailing commas, comments, unmatched quotes) all fail. The error carries fieldSelector '#pi-settings-config', so the form focuses the settings JSON editor after showing the inline error and toast.

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 a2e22f3302)

Solutions

  1. Fix the JSON so it parses to a plain object, e.g. { "apiKeyHelper": "/path/to/helper" } instead of [...] or a bare primitive
  2. Remove trailing commas, comments, and unquoted keys before saving
  3. Pre-check with the same rule and disable Save: parseJsonObject(text) !== null
  4. If settings are genuinely empty, keep the editor content as {}

Example fix

// before
settingsConfig: '["--flag", "--verbose"]'

// after
settingsConfig: '{ "args": ["--flag", "--verbose"] }'
Defensive patterns

Strategy: validation

Validate before calling

function parsesAsJsonObject(value: string): boolean {
  try {
    const parsed: unknown = JSON.parse(value);
    return !!parsed && typeof parsed === "object" && !Array.isArray(parsed);
  } catch {
    return false;
  }
}
// gate submission:
if (!parsesAsJsonObject(settingsConfig)) disableSave();

Type guard

function isJsonObjectText(value: string): value is string {
  if (!parsesAsJsonObject(value)) return false;
  return true;
}

Try / catch

try {
  await submit(identity);
} catch (error) {
  if (error instanceof Error && error.name === "PiFormValidationError" && error.message === t("jsonEditor.mustBeObject")) {
    focusSettingsEditor(); // equivalent of fieldSelector '#pi-settings-config'
    return;
  }
  throw error;
}

Prevention

When it happens

Trigger: Submitting with the settings JSON editor containing '[]', '"env": {...}' fragments, a bare string/number, JSON5-style trailing commas or comments, or content left in an intermediate/broken typing state.

Common situations: Pasting an array of env vars instead of an object; hand-editing the JSON editor and saving mid-edit; importing a settings snippet whose outer braces were lost; assuming comments are allowed in the editor.

Related errors


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