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
- Convert the plugin name to a cache-safe segment: lowercase, replace illegal chars with hyphens.
- Resolve scoped names before calling the cache (use the package's unscoped/base name as the catalog defines it).
- Verify against the marketplace catalog's declared plugin id rather than package.json name.
- 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
- Use the catalog's declared plugin id, not the npm package name, for cache keys
- Sanitize scoped/underscored npm names before caching
- Keep plugin names within the marketplace validator's charset when authoring
- Never interpolate slashes or dots into cache name components
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
- Invalid marketplace name for cache: "${marketplace}"
- Invalid version for cache: "${version}"
- Invalid path: ${localPath} resolves outside working director
- Destination paths cannot contain parent traversal or NUL byt
- Shared-folder destination escapes its configured root
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/653fa0e0e411027f.
Report an issue: GitHub.