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
- 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).
- Refresh/re-fetch the mod details to rule out a stale or truncated cached metadata response.
- If a specific mod always triggers this, report the malformed metadata to the mod author or Windhawk maintainers.
- 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
- Validate mod metadata against the settings schema before parsing (exactly one non-$ key per item).
- Catch per-item parse errors and skip bad entries so one malformed setting doesn't break the panel.
- Watch for accidental '$' prefixes on real setting keys when authoring mod metadata.
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
- Initial settings arrays must contain at least one template…
- Invalid object array schema definition.
- Mod id must be specified in the source code
- Failed to parse mod metadata
- Unknown setting type for value
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)