{"record":{"id":"aca37d1a09307b29","repo":"can1357/oh-my-pi","slug":"unrecognized-source-format-did-you-mean-sour","errorCode":null,"errorMessage":"Unrecognized source format. Did you mean './${source}' (local) or 'owner/repo' (GitHub)?","messagePattern":"Unrecognized source format\\. Did you mean '\\./(.+?)' \\(local\\) or 'owner/repo' \\(GitHub\\)\\?","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/extensibility/plugins/marketplace/fetcher.ts","lineNumber":83,"sourceCode":"\t\treturn \"git\";\n\t}\n\n\t// Rule 3: GitHub owner/repo shorthand (no protocol, no leading slash)\n\tif (GITHUB_SHORTHAND_RE.test(source)) {\n\t\treturn \"github\";\n\t}\n\n\t// Rule 4: Explicit relative or home-relative paths\n\tif (source.startsWith(\"./\") || source.startsWith(\"~/\")) {\n\t\treturn \"local\";\n\t}\n\n\t// Rule 5: Absolute paths — POSIX via path.isAbsolute, Windows via regex\n\tif (path.isAbsolute(source) || WIN_ABS_RE.test(source)) {\n\t\treturn \"local\";\n\t}\n\n\tthrow new Error(`Unrecognized source format. Did you mean './${source}' (local) or 'owner/repo' (GitHub)?`);\n}\n\n// ── parseMarketplaceCatalog ───────────────────────────────────────────\n\nfunction assertField(condition: boolean, field: string, filePath: string): void {\n\tif (!condition) {\n\t\tthrow new Error(`Missing or invalid field \"${field}\" in catalog: ${filePath}`);\n\t}\n}\n\n/**\n * Parse and validate a marketplace.json catalog from raw JSON content.\n *\n * Required fields: name (valid name segment), owner.name, plugins array.\n * Each plugin entry requires name (string) and source (string or object\n * with a \"source\" field). Extra fields are preserved via spread.\n *\n * @throws on JSON parse failure or missing/invalid required fields.","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/extensibility/plugins/marketplace/fetcher.ts#L65-L101","documentation":"classifySource recognizes exactly four source forms: http(s) URLs, git@/ssh:// URLs, GitHub owner/repo shorthand, and local paths (./, ~/, absolute POSIX or Windows). Any string matching none of these throws this error with a suggestion to prefix with ./ (local) or use owner/repo (GitHub).","triggerScenarios":"Passing a bare relative path without ./ (e.g. \"marketplace.json\", \"../mkt\"); single-token names like \"mymarketplace\" (no slash, so not owner/repo); URLs with non-http protocols (file://, git://); names with multiple slashes or illegal chars that fail GITHUB_SHORTHAND_RE.","commonSituations":"Users typing a relative directory/file name and omitting ./; paths like \"~/..\" written without the tilde prefix handled form; Windows drive paths on POSIX hosts without backslashes handled by WIN_ABS_RE edge cases; downstream config files storing unnormalized source strings.","solutions":["Prefix relative paths with \"./\" (or \"../\") so they classify as local.","Use \"owner/repo\" shorthand for GitHub marketplaces.","Use an absolute path or \"~/\"-prefixed path for local directories.","Use a full https:// URL for remote catalogs."],"exampleFix":"// before\nclassifySource(\"marketplaces/acme\"); // unrecognized\n// after\nclassifySource(\"./marketplaces/acme\"); // local\n// or\nclassifySource(\"acme/marketplace\"); // GitHub shorthand","handlingStrategy":"validation","validationCode":"function looksLikeSource(s: string): boolean {\n  return /^(https?:\\/\\/|git@|ssh:\\/\\/)\\S+/.test(s)\n    || /^[a-z0-9-]+\\/[a-z0-9._-]+$/i.test(s)\n    || s.startsWith(\"./\") || s.startsWith(\"../\") || s.startsWith(\"~/\")\n    || path.isAbsolute(s);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const type = classifySource(source);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"Unrecognized source format\")) {\n    console.error(`\"${source}\" — use ./rel/path, /abs/path, owner/repo, or https://...`);\n  } else throw err;\n}","preventionTips":["Always prefix relative paths with ./ or ../","Use owner/repo shorthand only for two-segment GitHub references","Use full https:// URLs for remote catalogs","Validate source strings against the accepted patterns before storing them in config"],"tags":["marketplace","parsing","validation","argument-error"],"backgroundTag":"unrecognized-source-format","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}