ramensoftware/windhawk · error

Unknown setting type for value

Error message

Unknown setting type for value: ${JSON.stringify(value)}

What it means

describeSetting() is a fall-through normalizer: after string, object-array, nested-object, and string-array branches all fail, it has no known SettingType for the value and throws with a JSON dump of it. It is the converter's exhaustiveness guard for unrecognized shapes.

Solutions

  1. Convert the value to a supported form: quote numbers/booleans as strings in the YAML
  2. Use a homogeneous string array for string-array settings
  3. Extend describeSetting with a branch if a new legitimate type must be supported

Example fix

// before
mySetting = 42
// after
mySetting = '42'
Defensive patterns

Strategy: type-guard

Validate before calling

const isSupportedSettingValue = (v: unknown): boolean =>
  typeof v === 'string' ||
  (Array.isArray(v) && (v.every(x => typeof x === 'string') || Array.isArray(v[0])));

Type guard

const isStringArray = (v: unknown): v is string[] =>
  Array.isArray(v) && v.every(x => typeof x === 'string');

Try / catch

try { desc = describeSetting(value); } catch (e) { if (e.message.startsWith('Unknown setting type')) console.warn('skipping unsupported setting', value); else throw e; }

Prevention

When it happens

Trigger: Passing a value like a bare number, boolean, plain object, or mixed array (not all strings) that matches none of isInitialSettingsCollection/isInitialSettingsArray/isStringArrayValue to describeSetting.

Common situations: Mod YAML uses a numeric or boolean initial value where only string/array forms are supported; mixed-type arrays from hand-edited settings blocks.

Related errors


AI-assisted analysis of ramensoftware/windhawk@61d99ed8e1 (2026-09-12). Data as JSON: /api/errors/eee7493889a5f246. Report an issue: GitHub.

Appendix: source

Thrown at src/windhawk-frontend/apps/windhawk-frontend/src/app/panel/mod-details/tabs/settings/core/yamlConverter.ts:206

    if (first.length === 0) {
      throw new Error('Invalid object array schema definition.');
    }
    return { kind: SettingType.ObjectArray, value: arrayValue, children: first };
  }

  if (isInitialSettingsArray(arrayValue)) {
    return { kind: SettingType.NestedObject, value: arrayValue, children: arrayValue };
  }

  if (isNumberArrayValue(arrayValue)) {
    return { kind: SettingType.NumberArray, value: arrayValue, defaultValue: 0 };
  }

  if (isStringArrayValue(arrayValue)) {
    return { kind: SettingType.StringArray, value: arrayValue, defaultValue: '' };
  }

  throw new Error(`Unknown setting type for value: ${JSON.stringify(value)}`);
}

// ============================================================================
// Utility Functions
// ============================================================================

export function parseIntLax(value?: string | number | null) {
  const result = parseInt((value ?? 0).toString(), 10);
  return Number.isNaN(result) ? 0 : result;
}

/**
 * Helper to check if a value is a plain object (not array, not null)
 */
export function isPlainObject(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

View on GitHub (pinned to 61d99ed8e1)