can1357/oh-my-pi · error · Error

Unknown feature "${feat}" in ${name}. Available: ${Object.ke

Error message

Unknown feature "${feat}" in ${name}. Available: ${Object.keys(plugin.manifest.features).join(", ")}

What it means

When setting a specific feature list via setEnabledFeatures, each requested feature is checked against the plugin's manifest.features object. A feature name that is not a key of that object throws this error listing the available features. It prevents silently enabling non-existent toggles.

Source

Thrown at packages/coding-agent/src/extensibility/plugins/manager.ts:873

		return config.plugins[name]?.enabledFeatures ?? null;
	}

	/**
	 * Set enabled features for a plugin.
	 */
	async setEnabledFeatures(name: string, features: string[] | null): Promise<void> {
		const config = await this.#ensureConfigLoaded();
		if (!config.plugins[name]) {
			throw new Error(`Plugin ${name} not found in runtime config`);
		}

		// Validate features if setting specific ones
		if (features && features.length > 0) {
			const plugin = await this.getPlugin(name, { path: path.join(getPluginsNodeModules(), name) });
			if (plugin?.manifest.features) {
				for (const feat of features) {
					if (!(feat in plugin.manifest.features)) {
						throw new Error(
							`Unknown feature "${feat}" in ${name}. Available: ${Object.keys(plugin.manifest.features).join(", ")}`,
						);
					}
				}
			}
		}

		config.plugins[name].enabledFeatures = features;
		await this.#saveRuntimeConfig();
	}

	// ==========================================================================
	// Settings
	// ==========================================================================

	/**
	 * Get all settings for a plugin.
	 */

View on GitHub (pinned to 9690622007)

Solutions

  1. Use the feature names listed in the error's "Available: ..." portion.
  2. Check the plugin's manifest.features keys and correct spelling/case.
  3. Update the plugin if the feature was added in a newer version.
  4. Pass null to reset to defaults instead of naming features.

Example fix

// before
await manager.setEnabledFeatures("my-plugin", ["autoformat"]);
// after (manifest has "auto-format")
await manager.setEnabledFeatures("my-plugin", ["auto-format"]);
Defensive patterns

Strategy: validation

Validate before calling

const plugin = await manager.getPlugin(name, { path: path.join(getPluginsNodeModules(), name) });
const available = new Set(Object.keys(plugin?.manifest.features ?? {}));
const unknown = features.filter(f => !available.has(f));
if (unknown.length > 0) {
  throw new Error(`Unknown features: ${unknown.join(", ")}. Available: ${[...available].join(", ")}`);
}

Try / catch

try {
  await manager.setEnabledFeatures(name, features);
} catch (err) {
  const m = err instanceof Error && err.message.match(/Unknown feature "([^"]+)".*Available: (.*)$/);
  if (m) {
    console.error(`"${m[1]}" invalid; valid features: ${m[2]}`);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling setEnabledFeatures(name, ["x"]) where "x" is not a key in the plugin manifest's features map; typos or renamed features; passing features to a plugin whose manifest has no features at all (validation is skipped, error only fires when features exist).

Common situations: Feature renamed in a plugin update while user config still lists the old name; copying feature names between plugins; case mismatch (features are exact keys).

Understand the failure class

Background: Invalid option value errors: "must be one of", "is not a valid", and "only allows" failures explained — this error's family across 23 libraries.

Related errors


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