ramensoftware/windhawk · error
Initial settings arrays must contain at least one template…
Error message
Initial settings arrays must contain at least one template entry.
What it means
describeSetting() normalizes a raw YAML settings value into a typed SettingDescriptor. When the value is neither a string nor a non-empty array, it throws because an 'initial settings' array must supply at least one template entry to derive the setting's structure. An empty array carries no schema information, so the converter refuses to guess.
Solutions
- Add at least one template entry to the settings array in the mod's YAML/INI block
- If the setting is genuinely optional, wrap it in a conditional so the key is omitted instead of given an empty array
- Change the value to a string if it is a scalar setting rather than an array
Example fix
// before
initial = []
// after
initial = [{ name: 'path', type: 'string', value: 'C:\\apps' }] Defensive patterns
Strategy: validation
Validate before calling
function hasInitialEntries(v: unknown): boolean {
return typeof v === 'string' || (Array.isArray(v) && v.length > 0);
}
if (!hasInitialEntries(raw)) throw new Error('settings initial value needs at least one entry'); Type guard
const isNonEmptyArray = (v: unknown): v is unknown[] => Array.isArray(v) && v.length > 0;
Try / catch
try { desc = describeSetting(raw); } catch (e) { if (e.message.includes('at least one template entry')) { desc = fallbackDescriptor(raw); } else { throw e; } } Prevention
- Never emit `initial = []` in generated mod settings; omit the key instead
- Validate mod YAML with a schema check before passing to describeSetting
- Add a unit test for empty-array settings input
When it happens
Trigger: Passing an empty array (e.g. `initial: []`) or null/undefined/non-array object to describeSetting, directly or via descriptor/schemaDescriptor/dataDescriptor while parsing a mod's [Settings] block whose initial value is `[]`.
Common situations: Mod authors write `1[] = []` style entries with no rows, or template generators emit empty arrays when no defaults exist; users copy a settings block and delete all entries.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Invalid object array schema definition.
- Unknown setting type for value
- Missing settings key
- Mod id must be specified in the source code
- archive is too large
AI-assisted analysis of ramensoftware/windhawk@61d99ed8e1 (2026-09-12).
Data as JSON: /api/errors/c43d3cdece1395cb.
Report an issue: GitHub.
Appendix: source
Thrown at src/windhawk-frontend/apps/windhawk-frontend/src/app/panel/mod-details/tabs/settings/core/yamlConverter.ts:181
* settings to describe. They hold a contract rather than degrade for a schema
* that broke it, which is why the render paths calling this do not guard against
* them.
*/
export function describeSetting(value: InitialSettingsValue): SettingDescriptor {
if (typeof value === 'boolean') {
return { kind: SettingType.Boolean, value, defaultValue: false };
}
if (typeof value === 'number') {
return { kind: SettingType.Number, value, defaultValue: 0 };
}
if (typeof value === 'string') {
return { kind: SettingType.String, value, defaultValue: '' };
}
if (!Array.isArray(value) || value.length === 0) {
throw new Error('Initial settings arrays must contain at least one template entry.');
}
const arrayValue: unknown[] = value;
if (isInitialSettingsCollection(arrayValue)) {
const [first] = arrayValue;
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 };View on GitHub (pinned to 61d99ed8e1)