{"record":{"id":"c43d3cdece1395cb","repo":"ramensoftware/windhawk","slug":"initial-settings-arrays-must-contain-at-least-one-template","errorCode":null,"errorMessage":"Initial settings arrays must contain at least one template entry.","messagePattern":"Initial settings arrays must contain at least one template entry\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/windhawk-frontend/apps/windhawk-frontend/src/app/panel/mod-details/tabs/settings/core/yamlConverter.ts","lineNumber":181,"sourceCode":" * settings to describe. They hold a contract rather than degrade for a schema\n * that broke it, which is why the render paths calling this do not guard against\n * them.\n */\nexport function describeSetting(value: InitialSettingsValue): SettingDescriptor {\n  if (typeof value === 'boolean') {\n    return { kind: SettingType.Boolean, value, defaultValue: false };\n  }\n\n  if (typeof value === 'number') {\n    return { kind: SettingType.Number, value, defaultValue: 0 };\n  }\n\n  if (typeof value === 'string') {\n    return { kind: SettingType.String, value, defaultValue: '' };\n  }\n\n  if (!Array.isArray(value) || value.length === 0) {\n    throw new Error('Initial settings arrays must contain at least one template entry.');\n  }\n\n  const arrayValue: unknown[] = value;\n\n  if (isInitialSettingsCollection(arrayValue)) {\n    const [first] = arrayValue;\n    if (first.length === 0) {\n      throw new Error('Invalid object array schema definition.');\n    }\n    return { kind: SettingType.ObjectArray, value: arrayValue, children: first };\n  }\n\n  if (isInitialSettingsArray(arrayValue)) {\n    return { kind: SettingType.NestedObject, value: arrayValue, children: arrayValue };\n  }\n\n  if (isNumberArrayValue(arrayValue)) {\n    return { kind: SettingType.NumberArray, value: arrayValue, defaultValue: 0 };","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/ramensoftware/windhawk/blob/61d99ed8e182e1af1b60109612b6763ad1b4b74e/src/windhawk-frontend/apps/windhawk-frontend/src/app/panel/mod-details/tabs/settings/core/yamlConverter.ts#L163-L199","documentation":"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.","triggerScenarios":"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 `[]`.","commonSituations":"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.","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"],"exampleFix":"// before\ninitial = []\n// after\ninitial = [{ name: 'path', type: 'string', value: 'C:\\\\apps' }]","handlingStrategy":"validation","validationCode":"function hasInitialEntries(v: unknown): boolean {\n  return typeof v === 'string' || (Array.isArray(v) && v.length > 0);\n}\nif (!hasInitialEntries(raw)) throw new Error('settings initial value needs at least one entry');","typeGuard":"const isNonEmptyArray = (v: unknown): v is unknown[] => Array.isArray(v) && v.length > 0;","tryCatchPattern":"try { desc = describeSetting(raw); } catch (e) { if (e.message.includes('at least one template entry')) { desc = fallbackDescriptor(raw); } else { throw e; } }","preventionTips":["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"],"tags":["yaml","validation","schema"],"backgroundTag":"empty-required-field","analyzedSha":"61d99ed8e182e1af1b60109612b6763ad1b4b74e","analyzedAt":"2026-09-12T14:02:41.115Z","contentChangedAt":"2026-09-12T14:02:41.115Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}