can1357/oh-my-pi · warning
Unsupported keybindings config extension: ${filePath}
Error message
Unsupported keybindings config extension: ${filePath} What it means
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.
Source
Thrown at packages/coding-agent/src/config/keybindings.ts:413
export interface KeybindingsCreateOptions {
/** Default-profile agent directory whose keybindings are merged before profile-specific bindings. */
inheritedAgentDir?: string;
}
/**
* Load raw config from a file synchronously.
* Returns parsed JSON/YAML or null if file doesn't exist or is invalid.
*/
function loadRawConfig(filePath: string): unknown {
try {
const content = fs.readFileSync(filePath, "utf-8");
if (filePath.endsWith(".json")) {
return JSONC.parse(content);
}
if (filePath.endsWith(".yml") || filePath.endsWith(".yaml")) {
return YAML.parse(content);
}
throw new Error(`Unsupported keybindings config extension: ${filePath}`);
} catch (error) {
if (isEnoent(error)) {
return null;
}
logger.warn("Failed to parse keybindings config", { path: filePath, error: String(error) });
return null;
}
}
function writeKeybindingsConfig(filePath: string, config: KeybindingsConfig): boolean {
try {
fs.writeFileSync(filePath, stringifyYamlConfig(config), "utf-8");
logger.debug("Migrated keybindings config", { path: filePath });
return true;
} catch (error) {
logger.warn("Failed to write migrated keybindings config", { path: filePath, error: String(error) });
return false;
}View on GitHub (pinned to 9690622007)
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
Example fix
// before ~/.omp/keybindings.toml (TOML content) // after ~/.omp/keybindings.yml (same keys converted to YAML)
Defensive patterns
Strategy: type-guard
Validate before calling
const KEYBIND_RE = /\.(json|ya?ml)$/;
function isSupportedKeybindingsPath(p: string): boolean {
return KEYBIND_RE.test(p);
} Type guard
const isYamlOrJsonKeybindings = (p: string): boolean => /\.(json|ya?ml)$/.test(p);
Try / catch
// loadRawConfig swallows its own throw into null, so guard the caller:
const raw = loadRawConfig(filePath);
if (raw === null && fs.existsSync(filePath)) {
logger.warn("Keybindings file exists but could not be parsed (likely unsupported extension)", { filePath });
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid config file path: ${readPath}
- Failed to load tree-sitter language: {err}
- sso-token-missing
- sso-token-expired
- Destination option ${key} must be a string
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/32931a198e93d5d9.
Report an issue: GitHub.