ramensoftware/windhawk · error

Missing settings key

Error message

Missing settings key

What it means

parseSettingItem processes a mod's setting definition where $-prefixed keys carry metadata and the remaining (non-$) keys must contain exactly one actual setting key. It throws 'Missing settings key' when every key in the object starts with '$', meaning there is no real setting to parse. This guards against malformed mod metadata that would produce a setting item with no name or value.

Solutions

  1. Inspect the mod's settings JSON and ensure exactly one non-$ key exists per setting item (e.g. remove the stray '$' prefix from the setting key).
  2. Refresh/re-fetch the mod details to rule out a stale or truncated cached metadata response.
  3. If a specific mod always triggers this, report the malformed metadata to the mod author or Windhawk maintainers.
  4. Caller-side: wrap parsing in try/catch and skip/reject the offending setting item so one bad entry doesn't break the whole details panel.

Example fix

// before (mod metadata)
{ "$type": "checkbox", "$label": "Enable", "$enabled": true }
// after
{ "$type": "checkbox", "$label": "Enable", "enabled": true }
Defensive patterns

Strategy: try-catch

Validate before calling

const actualKeys = Object.keys(setting).filter((k) => !k.startsWith('$'));
if (actualKeys.length !== 1) {
  console.warn('Setting item must have exactly one non-$ key', setting);
}

Try / catch

try {
  items = rawSettings.map(parseSettingItem);
} catch (e) {
  if (e.message === 'Missing settings key') {
    // skip the malformed item and continue rendering
    items = [];
  }
}

Prevention

When it happens

Trigger: Rendering mod details (ModDetails.Website.tsx:106) for a mod whose settings definition object contains only metadata keys like { "$type": ..., "$default": ... } with no actual setting key, or an empty object.

Common situations: A mod author published metadata with a typo where the setting key itself was accidentally prefixed with '$' (e.g. '$enabled' instead of 'enabled'); an upstream mods repository format change; truncated/failed JSON fetch yielding a metadata-only fragment.

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 ramensoftware/windhawk@61d99ed8e1 (2026-09-12). Data as JSON: /api/errors/942e6e0878fb2616. Report an issue: GitHub.

Appendix: source

Thrown at src/windhawk-frontend/apps/windhawk-frontend/src/app/panel/mod-details/ModDetails.Website.tsx:106

    if (!Array.isArray(settings)) {
      return null;
    }

    const parseSettings = (
      settingsArray: Record<string, unknown>[]
    ): InitialSettings => {
      return settingsArray.map(parseSettingItem);
    };

    const parseSettingItem = (
      value: Record<string, unknown>
    ): InitialSettingItem => {
      // Find the actual setting key (not starting with $)
      const actualParameters = Object.keys(value).filter(
        (x) => !x.startsWith('$')
      );
      if (actualParameters.length === 0) {
        throw new Error('Missing settings key');
      } else if (actualParameters.length > 1) {
        throw new Error('More than one settings key');
      }

      const actualParameter = actualParameters[0];
      const metaParameters = Object.keys(value).filter((x) =>
        x.startsWith('$')
      );

      // Group meta parameters by their base name (name, description, options)
      const metaGroups: Record<
        string,
        Array<{ language: string | null; value: unknown }>
      > = {};

      for (const paramWithPrefix of metaParameters) {
        const param = paramWithPrefix.slice(1); // remove '$'
        const paramParts = param.split(':');

View on GitHub (pinned to 61d99ed8e1)