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

  1. Rename the file to keybindings.yml (or .yaml/.json) with matching content format
  2. If the file is TOML/INI/other, convert its content to YAML or JSON
  3. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/32931a198e93d5d9. Report an issue: GitHub.