{"record":{"id":"65cfca6748ef4e47","repo":"stablyai/orca","slug":"unable-to-parse-shortcut","errorCode":null,"errorMessage":"Unable to parse shortcut.","messagePattern":"Unable to parse shortcut\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/keybindings/keybinding-file.ts","lineNumber":124,"sourceCode":"    return Array.isArray(normalized)\n      ? { ok: true, value: normalized }\n      : normalized.ok\n        ? { ok: true, value: [normalized.value] }\n        : normalized\n  }\n  return { ok: false, error: 'Use a string, string array, null, or false.' }\n}\n\nfunction normalizeWriteBindingValue(actionId: KeybindingActionId, value: unknown): string[] | null {\n  if (value === null) {\n    return null\n  }\n  if (!Array.isArray(value) || !value.every((binding) => typeof binding === 'string')) {\n    throw new Error('Use a string array or null.')\n  }\n  const normalized = normalizeKeybindingArrayForAction(actionId, value)\n  if (!Array.isArray(normalized)) {\n    throw new Error(normalized.ok ? 'Unable to parse shortcut.' : normalized.error)\n  }\n  return normalized\n}\n\nfunction parseBindingSection(\n  value: unknown,\n  section: string,\n  diagnostics: KeybindingFileDiagnostic[],\n  options: { skipRootKeys?: boolean } = {}\n): KeybindingOverrides {\n  if (value === undefined) {\n    return {}\n  }\n  if (!isJsonObject(value)) {\n    diagnostics.push({\n      severity: 'error',\n      section,\n      message: `${section} must be an object.`","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/keybindings/keybinding-file.ts#L106-L142","documentation":"Thrown by normalizeWriteBindingValue when normalizeKeybindingArrayForAction returns a non-array result whose .ok is true — i.e. a single normalized binding object instead of the expected array form. The 'Unable to parse shortcut.' message is the fallback when no specific error string was produced, signalling an internal shape inconsistency in the per-action normalizer.","triggerScenarios":"The per-action normalizer for an actionId returned a single-binding success object ({ok:true,value}) rather than an array, while the write path expected an array. This is an internal/programming error, not a user typo.","commonSituations":"A new KeybindingActionId was added whose normalizer has a different return shape, or the action's binding semantics were changed to single-binding without updating the write path.","solutions":["Check normalizeKeybindingArrayForAction for the offending actionId and ensure it returns string[] on success.","Report the actionId to the Orca maintainers with the value that triggered it.","As a workaround, re-enter the binding through the UI capture control which produces array form."],"exampleFix":"// before\nfunction normalizeKeybindingArrayForAction(actionId, value) { return { ok: true, value: 'Cmd+K' } }\n// after\nfunction normalizeKeybindingArrayForAction(actionId, value) { return ['Cmd+K'] }","handlingStrategy":"try-catch","validationCode":"const normalized = normalizeKeybindingArrayForAction(actionId, value)\nif (!Array.isArray(normalized)) reportInternalNormalizerShape(actionId, normalized)","typeGuard":"function isStringArray(v: unknown): v is string[] { return Array.isArray(v) && v.every((x) => typeof x === 'string') }","tryCatchPattern":"try { writeKeybindingOverride(path, platform, actionId, bindings) }\ncatch (e) { if (/Unable to parse shortcut/.test(String((e as Error).message))) reportOrcaBug(actionId, bindings); else throw e }","preventionTips":["Report actionIds that hit this path — it indicates an internal normalizer inconsistency.","Use the UI capture control to produce well-formed array bindings.","Add a unit test asserting each KeybindingActionId normalizer returns string[] on success."],"tags":["keybindings","parse","internal"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}