affaan-m/ECC · error

Invalid repo format: " ". Expected "owner/repo".

Error message

Invalid repo format: "${repo}". Expected "owner/repo".

What it means

normalizeRepo converts a repository reference string into { owner, name } by splitting on '/' and requiring exactly two non-empty segments. Any input that doesn't yield exactly two parts — full URLs, 'owner/name/extra', empty strings, values without a slash, or non-string inputs coerced via String() — is rejected with this error naming the received value.

Solutions

  1. Pass the canonical 'owner/name' string form
  2. Strip the URL prefix if you have a full URL: new URL(repo).pathname.replace(/^\//, '') then validate
  3. Resolve the repo from process.env.GITHUB_REPOSITORY when not explicitly provided
  4. Pre-validate with a regex like /^[^/]+\/[^/]+$/ before calling

Example fix

// before
listIssues('https://github.com/acme/widgets', ...) // 4 parts -> throws
// after
const repo = process.env.GITHUB_REPOSITORY || 'acme/widgets'; // 'acme/widgets'
listIssues(repo, ...)
Defensive patterns

Strategy: validation

Validate before calling

function parseRepo(repo) { const m = /^(?:https:\/\/github\.com\/)?([\w.-]+)\/([\w.-]+)$/.exec(String(repo || '').replace(/\.git$/, '')); if (!m) throw new Error(`bad repo: ${repo}`); return { owner: m[1], name: m[2] }; }

Type guard

const isOwnerName = (v) => typeof v === 'string' && /^[^/\s]+\/[^/\s]+$/.test(v.trim());

Try / catch

try { listIssues(repo, opts); } catch (e) { if (String(e.message).includes('Invalid repo format')) console.error(`normalize '${e.message.match(/"(.*)"/)?.[1]}' to owner/name before calling`); throw e; }

Prevention

When it happens

Trigger: Passing 'owner' (no slash), 'https://github.com/owner/name' (four parts), 'owner//name' (still fine after filtering, but 'a/b/c' fails), an empty string, or undefined/null (coerced to '') into normalizeRepo or any gh-api call that takes a repo.

Common situations: Passing a GitHub URL instead of the 'owner/name' shorthand; GITHUB_REPOSITORY missing so an empty string is used; repo names containing slashes for nested services mistakenly assumed supported; concatenating owner and name with the wrong separator.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/35f3224247d0c747. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/github-coordination/gh-api.js:8

'use strict';

const { spawnSync } = require('child_process');

function normalizeRepo(repo) {
  const parts = String(repo || '').split('/').filter(Boolean);
  if (parts.length !== 2) {
    throw new Error(`Invalid repo format: "${repo}". Expected "owner/repo".`);
  }
  const [owner, name] = parts;
  return { owner, name };
}

function normalizeIssueNumber(value) {
  const parsed = Number.parseInt(String(value), 10);
  if (!Number.isFinite(parsed) || parsed <= 0) {
    throw new Error(`Invalid issue number: ${value}`);
  }
  return parsed;
}

function normalizeLabelValue(label) {
  if (typeof label === 'string') {
    return label.trim();
  }
  if (label && typeof label === 'object') {

View on GitHub (pinned to 8321021c54)