can1357/oh-my-pi · error · Error
Unrecognized source format. Did you mean './${source}' (loca
Error message
Unrecognized source format. Did you mean './${source}' (local) or 'owner/repo' (GitHub)? What it means
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).
Source
Thrown at packages/coding-agent/src/extensibility/plugins/marketplace/fetcher.ts:83
return "git";
}
// Rule 3: GitHub owner/repo shorthand (no protocol, no leading slash)
if (GITHUB_SHORTHAND_RE.test(source)) {
return "github";
}
// Rule 4: Explicit relative or home-relative paths
if (source.startsWith("./") || source.startsWith("~/")) {
return "local";
}
// Rule 5: Absolute paths — POSIX via path.isAbsolute, Windows via regex
if (path.isAbsolute(source) || WIN_ABS_RE.test(source)) {
return "local";
}
throw new Error(`Unrecognized source format. Did you mean './${source}' (local) or 'owner/repo' (GitHub)?`);
}
// ── parseMarketplaceCatalog ───────────────────────────────────────────
function assertField(condition: boolean, field: string, filePath: string): void {
if (!condition) {
throw new Error(`Missing or invalid field "${field}" in catalog: ${filePath}`);
}
}
/**
* Parse and validate a marketplace.json catalog from raw JSON content.
*
* Required fields: name (valid name segment), owner.name, plugins array.
* Each plugin entry requires name (string) and source (string or object
* with a "source" field). Extra fields are preserved via spread.
*
* @throws on JSON parse failure or missing/invalid required fields.View on GitHub (pinned to 9690622007)
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.
Example fix
// before
classifySource("marketplaces/acme"); // unrecognized
// after
classifySource("./marketplaces/acme"); // local
// or
classifySource("acme/marketplace"); // GitHub shorthand Defensive patterns
Strategy: validation
Validate before calling
function looksLikeSource(s: string): boolean {
return /^(https?:\/\/|git@|ssh:\/\/)\S+/.test(s)
|| /^[a-z0-9-]+\/[a-z0-9._-]+$/i.test(s)
|| s.startsWith("./") || s.startsWith("../") || s.startsWith("~/")
|| path.isAbsolute(s);
} Try / catch
try {
const type = classifySource(source);
} catch (err) {
if (err instanceof Error && err.message.startsWith("Unrecognized source format")) {
console.error(`"${source}" — use ./rel/path, /abs/path, owner/repo, or https://...`);
} else throw err;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- expected owner/repo#NN or https://github.com/owner/repo/issu
- Unknown changelog category: ${raw}
- No JSON payload found in response
- Line numbers in @@ header must be >= 1
- Line hint must be >= 1
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/aca37d1a09307b29.
Report an issue: GitHub.