can1357/oh-my-pi · error · Error
Invalid marketplace name for cache: "${marketplace}"
Error message
Invalid marketplace name for cache: "${marketplace}" What it means
The marketplace cache builds directory names as <marketplace>___<pluginName>___<version>, so every component is validated with isValidNameSegment (lowercase alnum + hyphens, max 64 chars) to prevent path traversal. A marketplace value failing that check throws this error before any filesystem operation.
Source
Thrown at packages/coding-agent/src/extensibility/plugins/marketplace/cache.ts:33
import * as path from "node:path";
import { isEnoent } from "@oh-my-pi/pi-utils";
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,View on GitHub (pinned to 9690622007)
Solutions
- Normalize the marketplace identifier to lowercase alphanumeric + hyphens before caching.
- Strip protocols, whitespace, and path separators from the marketplace string.
- Check length is ≤ 64 characters.
- Fix the source that produced the marketplace name (catalog field or CLI argument).
Example fix
// before getCachedPluginPath(dir, "https://github.com/acme/mkt", "plugin", "1.0.0"); // after getCachedPluginPath(dir, "acme-mkt", "plugin", "1.0.0");
Defensive patterns
Strategy: validation
Validate before calling
import { isValidNameSegment } from ".../marketplace/types";
if (!isValidNameSegment(marketplace)) {
throw new Error(`Sanitize marketplace name before caching: ${marketplace}`);
} 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, plugin, version);
} catch (err) {
if (err instanceof Error && err.message.includes("Invalid marketplace name")) {
console.error(`Marketplace id "${marketplace}" must be lowercase alnum/hyphens (≤64)`);
} else throw err;
} Prevention
- Normalize marketplace ids to lowercase alnum + hyphens at ingestion time
- Strip protocols and separators from URLs before deriving a marketplace name
- Enforce the ≤64-char limit when creating marketplaces
- Never pass raw user/URL strings as cache path components
When it happens
Trigger: Calling getCachedPluginPath (directly or via cache lookup during plugin install) with a marketplace containing uppercase letters, slashes, dots, spaces, or exceeding 64 chars.
Common situations: Marketplace name parsed from a URL with protocol/slashes included; user-supplied marketplace string not normalized; case-preserved names from an upstream catalog.
Related errors
- Invalid plugin name for cache: "${pluginName}"
- 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/13a3ac0526c06558.
Report an issue: GitHub.