can1357/oh-my-pi · error · Error

Invalid plugin name for cache: "${pluginName}"

Error message

Invalid plugin name for cache: "${pluginName}"

What it means

Same cache-path validation: the plugin name must satisfy isValidNameSegment (lowercase alnum + hyphens, ≤64) because it becomes a directory-name component. Anything else (dots, underscores, slashes, uppercase, empty, too long) is rejected to block path traversal.

Source

Thrown at packages/coding-agent/src/extensibility/plugins/marketplace/cache.ts:36

import { isValidNameSegment } from "./types";

// Reject anything that could be used for path traversal or shell injection in
// version strings. Only printable, unambiguous characters are allowed.
const VERSION_RE = /^[a-zA-Z0-9._+-]+$/;

/** Return true when `version` is safe for use as a cache path component. */
export function isValidVersionForCache(version: string): boolean {
	// prevent path-traversal sequences like ".." or "1..2"
	return version.length > 0 && version.length <= 128 && VERSION_RE.test(version) && !version.includes("..");
}

function validateCacheComponents(marketplace: string, pluginName: string, version: string): void {
	if (!isValidNameSegment(marketplace)) {
		throw new Error(`Invalid marketplace name for cache: "${marketplace}"`);
	}
	if (!isValidNameSegment(pluginName)) {
		throw new Error(`Invalid plugin name for cache: "${pluginName}"`);
	}
	if (!isValidVersionForCache(version)) {
		throw new Error(`Invalid version for cache: "${version}"`);
	}
}

/**
 * Return the absolute path for a cached plugin directory.
 * Throws if any component fails validation.
 */
export function getCachedPluginPath(
	cacheDir: string,
	marketplace: string,
	pluginName: string,
	version: string,
): string {
	validateCacheComponents(marketplace, pluginName, version);
	return path.join(cacheDir, `${marketplace}___${pluginName}___${version}`);

View on GitHub (pinned to 9690622007)

Solutions

  1. Convert the plugin name to a cache-safe segment: lowercase, replace illegal chars with hyphens.
  2. Resolve scoped names before calling the cache (use the package's unscoped/base name as the catalog defines it).
  3. Verify against the marketplace catalog's declared plugin id rather than package.json name.
  4. Ensure length ≤ 64 and non-empty.

Example fix

// before
getCachedPluginPath(dir, "acme", "@acme/my_plugin", "1.0.0");
// after
getCachedPluginPath(dir, "acme", "acme-my-plugin", "1.0.0");
Defensive patterns

Strategy: validation

Validate before calling

import { isValidNameSegment } from ".../marketplace/types";
if (!isValidNameSegment(pluginName)) {
  pluginName = pluginName.toLowerCase().replace(/[^a-z0-9-]/g, "-").slice(0, 64);
}

Type guard

function isCacheSafeName(s: string): boolean {
  return s.length > 0 && s.length <= 64 && /^[a-z0-9-]+$/.test(s);
}

Try / catch

try {
  const p = getCachedPluginPath(dir, marketplace, pluginName, version);
} catch (err) {
  if (err instanceof Error && err.message.includes("Invalid plugin name")) {
    console.error(`Plugin name "${pluginName}" must be lowercase alnum/hyphens (≤64)`);
  } else throw err;
}

Prevention

When it happens

Trigger: getCachedPluginPath called with a plugin name like "my_plugin", "My.Plugin", "scope/pkg", "", or a >64-char name.

Common situations: Scoped npm names (@scope/pkg) passed unmodified; names taken verbatim from package.json where underscores are allowed; version-derived or URL-derived strings used as names.

Related errors


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