{"record":{"id":"32931a198e93d5d9","repo":"can1357/oh-my-pi","slug":"unsupported-keybindings-config-extension-filepa","errorCode":null,"errorMessage":"Unsupported keybindings config extension: ${filePath}","messagePattern":"Unsupported keybindings config extension: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/coding-agent/src/config/keybindings.ts","lineNumber":413,"sourceCode":"export interface KeybindingsCreateOptions {\n\t/** Default-profile agent directory whose keybindings are merged before profile-specific bindings. */\n\tinheritedAgentDir?: string;\n}\n\n/**\n * Load raw config from a file synchronously.\n * Returns parsed JSON/YAML or null if file doesn't exist or is invalid.\n */\nfunction loadRawConfig(filePath: string): unknown {\n\ttry {\n\t\tconst content = fs.readFileSync(filePath, \"utf-8\");\n\t\tif (filePath.endsWith(\".json\")) {\n\t\t\treturn JSONC.parse(content);\n\t\t}\n\t\tif (filePath.endsWith(\".yml\") || filePath.endsWith(\".yaml\")) {\n\t\t\treturn YAML.parse(content);\n\t\t}\n\t\tthrow new Error(`Unsupported keybindings config extension: ${filePath}`);\n\t} catch (error) {\n\t\tif (isEnoent(error)) {\n\t\t\treturn null;\n\t\t}\n\t\tlogger.warn(\"Failed to parse keybindings config\", { path: filePath, error: String(error) });\n\t\treturn null;\n\t}\n}\n\nfunction writeKeybindingsConfig(filePath: string, config: KeybindingsConfig): boolean {\n\ttry {\n\t\tfs.writeFileSync(filePath, stringifyYamlConfig(config), \"utf-8\");\n\t\tlogger.debug(\"Migrated keybindings config\", { path: filePath });\n\t\treturn true;\n\t} catch (error) {\n\t\tlogger.warn(\"Failed to write migrated keybindings config\", { path: filePath, error: String(error) });\n\t\treturn false;\n\t}","sourceCodeStart":395,"sourceCodeEnd":431,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/config/keybindings.ts#L395-L431","documentation":"loadRawConfig parses keybinding config files as JSONC for .json or YAML for .yml/.yaml. Any other extension is unsupported, so it throws. Notably, the throw is caught inside the same function, logged via logger.warn, and converted to a null return — callers see null rather than a thrown error.","triggerScenarios":"The keybindings loader resolves a file path with an unsupported extension — e.g. keybindings.toml, keybindings.conf, or a file with no extension — and readFileSync succeeds, reaching the parser-dispatch branch.","commonSituations":"User created keybindings in another format (TOML from another tool), copied a keybindings file without its extension, or pointed a profile/agent-dir override at a non-standard filename.","solutions":["Rename the file to keybindings.yml (or .yaml/.json) with matching content format","If the file is TOML/INI/other, convert its content to YAML or JSON","Check that the agent-dir/profile path configuration isn't pointing at a differently named keybindings file"],"exampleFix":"// before\n~/.omp/keybindings.toml   (TOML content)\n// after\n~/.omp/keybindings.yml   (same keys converted to YAML)","handlingStrategy":"type-guard","validationCode":"const KEYBIND_RE = /\\.(json|ya?ml)$/;\nfunction isSupportedKeybindingsPath(p: string): boolean {\n\treturn KEYBIND_RE.test(p);\n}","typeGuard":"const isYamlOrJsonKeybindings = (p: string): boolean => /\\.(json|ya?ml)$/.test(p);","tryCatchPattern":"// loadRawConfig swallows its own throw into null, so guard the caller:\nconst raw = loadRawConfig(filePath);\nif (raw === null && fs.existsSync(filePath)) {\n\tlogger.warn(\"Keybindings file exists but could not be parsed (likely unsupported extension)\", { filePath });\n}","preventionTips":["Name keybinding files exactly keybindings.yml, keybindings.yaml, or keybindings.json","Convert third-party (TOML/INI) keybinding files to YAML before placing them in the agent dir","Don't copy keybindings files without preserving the extension; the extension selects the parser","Remember an unsupported extension yields null (logged warning), so check for null plus file existence if you need to surface the problem"],"tags":["keybindings","config","unsupported-extension"],"backgroundTag":"unsupported-config-file-extension","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}