nexu-io/open-design · error · Error
public_github_repository_metric only supports /repos/{owner}
Error message
public_github_repository_metric only supports /repos/{owner}/{repo} URLs What it means
Thrown by selectGithubRepositoryApiUrl when the URL host/scheme are correct but the pathname does not match /^\/repos\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/. The tool only fetches a single repository resource via the canonical /repos/{owner}/{repo} endpoint; deeper paths, query endpoints, or non-repository paths are rejected to keep the response shape bounded and predictable.
Source
Thrown at apps/daemon/src/live-artifacts/refresh.ts:664
});
}
function selectGithubRepositoryApiUrl(input: PublicGithubRepositoryMetricInput): URL {
const rawUrl = optionalString(input.url, 'input.url');
if (rawUrl === undefined) throw new Error('public_github_repository_metric requires input.url');
let url: URL;
try {
url = new URL(rawUrl);
} catch {
throw new Error('public_github_repository_metric input.url must be a valid URL');
}
if (url.protocol !== 'https:' || url.hostname !== 'api.github.com') {
throw new Error('public_github_repository_metric only supports https://api.github.com repository URLs');
}
if (!/^\/repos\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(url.pathname)) {
throw new Error('public_github_repository_metric only supports /repos/{owner}/{repo} URLs');
}
url.search = '';
url.hash = '';
url.username = '';
url.password = '';
return url;
}
function selectGithubFields(input: PublicGithubRepositoryMetricInput): string[] {
if (input.fields === undefined) return ['stargazers_count', 'full_name', 'html_url', 'updated_at'];
if (!Array.isArray(input.fields)) throw new Error('input.fields must be an array of strings');
const fields = input.fields.filter((field): field is string => typeof field === 'string');
if (fields.length !== input.fields.length) throw new Error('input.fields must be an array of strings');
return fields.slice(0, 20);
}
async function executePublicGithubRepositoryMetric(options: ExecuteLocalDaemonRefreshSourceOptions): Promise<BoundedJsonObject> {
const input = options.source.input as PublicGithubRepositoryMetricInput;View on GitHub (pinned to 5be4028344)
Solutions
- Use exactly the form /repos/{owner}/{repo} with no trailing slash and no sub-resource path.
- For sub-resources (issues, releases), do not use this tool; it is scoped to repository-level metrics only.
- Verify owner/repo segments only contain allowed characters; rename or encode if necessary (encoding is not supported here).
Example fix
// before
input: { url: 'https://api.github.com/repos/octocat/Hello-World/issues' }
// after
input: { url: 'https://api.github.com/repos/octocat/Hello-World' } Defensive patterns
Strategy: validation
Validate before calling
const REPO_PATH = /^\/repos\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
function assertRepoPath(u: URL): void {
if (!REPO_PATH.test(u.pathname)) throw new Error('expected /repos/{owner}/{repo}');
} Type guard
function isRepoApiUrl(v: unknown): v is string {
if (typeof v !== 'string') return false;
try {
const u = new URL(v);
return u.protocol === 'https:' && u.hostname === 'api.github.com'
&& /^\/repos\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(u.pathname);
} catch { return false; }
} Prevention
- Do not append sub-resources (issues, releases, comments) — the tool fetches repo-level data only.
- Avoid trailing slashes; keep the path normalized.
- When in doubt, build the URL from owner + repo strings rather than copying a URL.
When it happens
Trigger: Pathname is '/repos/octocat' (missing repo), '/repos/octocat/Hello-World/issues' (sub-resource), '/users/octocat' (wrong endpoint), '/repos/foo/bar/' (trailing slash), or contains disallowed characters in owner/repo segments (e.g. spaces, slashes).
Common situations: Model tries to fetch a specific issue or release endpoint by extending the path; developer appends query strings or fragments (these are stripped earlier but path depth still fails); owner or repo contains characters outside [A-Za-z0-9_.-] (rare but possible with renamed/special repos).
Related errors
- public_github_repository_metric input.url must be a valid UR
- public_github_repository_metric only supports https://api.gi
- input.fields must be an array of strings
- connector refresh source requires connector metadata
- ${field} must be a dot-separated JSON path
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/e8b48254a9626b49.
Report an issue: GitHub.