{"record":{"id":"0028abc25a95f378","repo":"can1357/oh-my-pi","slug":"invalid-marketplace-name-marketplace","errorCode":null,"errorMessage":"Invalid marketplace name: \"${marketplace}\"","messagePattern":"Invalid marketplace name: \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/extensibility/plugins/marketplace/types.ts","lineNumber":29,"sourceCode":"\n// ── Plugin ID helpers ────────────────────────────────────────────────\n\nconst NAME_RE = /^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$/;\nconst MAX_NAME_LENGTH = 64;\nconst MAX_ID_LENGTH = 128;\n\n/** Validate a plugin or marketplace name segment. */\nexport function isValidNameSegment(s: string): boolean {\n\treturn s.length > 0 && s.length <= MAX_NAME_LENGTH && NAME_RE.test(s);\n}\n\n/** Build canonical plugin ID: `\"name@marketplace\"`. Both segments are validated. */\nexport function buildPluginId(name: string, marketplace: string): string {\n\tif (!isValidNameSegment(name)) {\n\t\tthrow new Error(`Invalid plugin name: \"${name}\"`);\n\t}\n\tif (!isValidNameSegment(marketplace)) {\n\t\tthrow new Error(`Invalid marketplace name: \"${marketplace}\"`);\n\t}\n\tconst id = `${name}@${marketplace}`;\n\tif (id.length > MAX_ID_LENGTH) {\n\t\tthrow new Error(`Plugin ID exceeds ${MAX_ID_LENGTH} characters: \"${id}\"`);\n\t}\n\treturn id;\n}\n\n/** Parse `\"name@marketplace\"` → `{ name, marketplace }` or `null`. */\nexport function parsePluginId(id: string): { name: string; marketplace: string } | null {\n\tconst atIndex = id.lastIndexOf(\"@\");\n\tif (atIndex <= 0 || atIndex === id.length - 1) return null;\n\n\tconst name = id.slice(0, atIndex);\n\tconst marketplace = id.slice(atIndex + 1);\n\n\tif (!isValidNameSegment(name) || !isValidNameSegment(marketplace)) return null;\n","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/extensibility/plugins/marketplace/types.ts#L11-L47","documentation":"The marketplace segment of buildPluginId failed isValidNameSegment: it must be 1–64 characters, lowercase alphanumerics with internal dots/hyphens, no leading/trailing dot or hyphen, and no `@` (which would break the `name@marketplace` ID format). This indicates the marketplace identifier supplied to the ID builder is malformed — usually from a hand-edited or generated marketplace registry name.","triggerScenarios":"Calling buildPluginId(name, marketplace) with an empty marketplace string, one longer than 64 chars, containing uppercase/underscores/spaces/`@`, or a value like `my-market-` (trailing hyphen) or `Corp Market` (space).","commonSituations":"A user's marketplace config file has a marketplace key like `Work_Marketplace` or an empty name field; tooling derives the marketplace name from a URL (leaving `github.com` with slashes/dots in wrong places) or from a display label; marketplace renamed and old capitalized names remain in config.","solutions":["Fix the marketplace name in the config/catalog to a valid slug: /^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$/, ≤64 chars.","Normalize programmatically (lowercase, strip invalid chars, trim edge dots/hyphens) before calling buildPluginId.","Guard with isValidNameSegment(marketplace) before building and report a config error to the user naming the offending marketplace entry.","If the marketplace identifier legitimately contains uppercase or underscores (e.g. an org name), mint a separate lowercase slug field for it."],"exampleFix":"// before\nconst id = buildPluginId(\"my-tool\", \"Acme Market\");\n// after\nconst id = buildPluginId(\"my-tool\", \"acme-market\");","handlingStrategy":"validation","validationCode":"if (!isValidNameSegment(marketplace)) {\n\tthrow new Error(`Marketplace name must match /^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$/ (1-64 chars, no \"@\"): \"${marketplace}\"`);\n}","typeGuard":"function isMarketplaceName(v: unknown): v is string {\n\treturn typeof v === \"string\" && /^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$/.test(v) && v.length <= 64 && !v.includes(\"@\");\n}","tryCatchPattern":"let id: string;\ntry {\n\tid = buildPluginId(name, marketplace);\n} catch (err) {\n\tif (err instanceof Error && err.message.startsWith('Invalid marketplace name')) {\n\t\tthrow new Error(`Fix the marketplace entry \"${marketplace}\" in your plugin config: lowercase slug required.`);\n\t}\n\tthrow err;\n}","preventionTips":["Store marketplace identifiers as lowercase kebab slugs, not display names.","Derive marketplace names from a dedicated `name` field, never from URLs or org titles.","Validate marketplace names at config load time so bad entries are caught before ID construction.","Avoid `@` and uppercase in marketplace keys; they break both ID parsing and the segment regex."],"tags":["validation","naming","marketplace","plugin-id"],"backgroundTag":"invalid-name-segment","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}