{"record":{"id":"ad9cc314a69ef61e","repo":"siyuan-note/siyuan","slug":"unsupported-shortcut-binding-version","errorCode":null,"errorMessage":"Unsupported shortcut binding version","messagePattern":"Unsupported shortcut binding version","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"app/src/util/keymapBindings.ts","lineNumber":47,"sourceCode":"    bindings?: IShortcutBindings;\n}\n\nexport const getKeymapBindings = (item?: IShortcutKeymap): string[] => {\n    if (!item) {\n        return [];\n    }\n    if (item.bindings) {\n        if (item.bindings.version !== 1 || !Array.isArray(item.bindings.keys)) {\n            return [];\n        }\n        return [...new Set(item.bindings.keys.filter((key): key is string => typeof key === \"string\" && key.length > 0))];\n    }\n    return typeof item.custom === \"string\" && item.custom ? [item.custom] : [];\n};\n\nexport const setKeymapBindings = (item: IShortcutKeymap, keys: string[]) => {\n    if (item.bindings && item.bindings.version !== 1) {\n        throw new Error(\"Unsupported shortcut binding version\");\n    }\n    const uniqueKeys = [...new Set(keys.filter(Boolean))];\n    const priority = Object.fromEntries(Object.entries(item.bindings?.priority || {})\n        .filter(([key]) => uniqueKeys.some(hotkey => key === hotkey || key.endsWith(\":\" + hotkey))));\n    item.bindings = {...item.bindings, version: 1, keys: uniqueKeys, priority};\n    item.custom = uniqueKeys[0] || \"\";\n};\n\nexport const getKeymapItem = (keymap: object, path: readonly string[]): IShortcutKeymap | undefined => {\n    let value: unknown = keymap;\n    for (const key of path) {\n        if (!value || typeof value !== \"object\" || !Object.prototype.hasOwnProperty.call(value, key)) {\n            return undefined;\n        }\n        value = (value as Record<string, unknown>)[key];\n    }\n    return value && typeof value === \"object\" && typeof (value as IShortcutKeymap).custom === \"string\" ?\n        value as IShortcutKeymap : undefined;","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/app/src/util/keymapBindings.ts#L29-L65","documentation":"setKeymapBindings enforces that an IShortcutKeymap carrying a bindings object uses bindings.version === 1. If a bindings object exists with any other version, the library throws because it cannot safely interpret or migrate an unknown binding format. Maps without a bindings field are fine and are initialized to version 1.","triggerScenarios":"Calling setKeymapBindings (app/src/util/keymapBindings.ts:47) with an item whose bindings.version is absent-but-object? no — present and not 1: e.g. bindings: {version: 2, ...} produced by a newer/older app version or hand-edited JSON in the keymap config.","commonSituations":"Downgrading the app after keymap format changed; merging keymap JSON from another user/installation; plugins or sync writing newer binding versions; hand-editing appearance config files.","solutions":["Remove or reset the bindings field on the keymap item so it is regenerated as version 1","Update the app to the version that wrote the newer bindings format","Delete the stale keymap JSON and let the app rebuild default bindings","Catch the error and reinitialize item.bindings to {version: 1} before retrying"],"exampleFix":"// before\nsetKeymapBindings(item, keys); // item.bindings.version === 2\n// after\ndelete item.bindings; // or migrate version 2 to version 1\nsetKeymapBindings(item, keys);","handlingStrategy":"validation","validationCode":"if (item.bindings && item.bindings.version !== 1) {\n    delete item.bindings; // reset unknown format before calling\n}\nsetKeymapBindings(item, keys);","typeGuard":"const isV1 = (item) => !item.bindings || item.bindings.version === 1;","tryCatchPattern":"try { setKeymapBindings(item, keys); } catch (e) { if (e.message.includes(\"binding version\")) { delete item.bindings; setKeymapBindings(item, keys); } }","preventionTips":["Do not hand-edit keymap JSON bindings versions","Upgrade the app instead of loading newer keymap formats into older versions","Reset bindings to defaults when format errors occur"],"tags":["keymap","versioning","config"],"backgroundTag":"unsupported-config-value","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}