nodejs/node · error · Error

${this.constructor.providerEntity} must be specified in the

Error message

${this.constructor.providerEntity} must be specified in the format owner/repository

What it means

Thrown by the GitHub trust provider's `validateEntity` when the entity string, split on `/`, does not have exactly two segments. The required shape is `owner/repository`, matching a GitHub repository coordinate.

Source

Thrown at deps/npm/lib/commands/trust/github.js:60

    trustDefinitions['allow-publish'],
    trustDefinitions['allow-stage-publish'],
    // globals are alphabetical
    globalDefinitions['dry-run'],
    globalDefinitions.json,
    globalDefinitions.registry,
    globalDefinitions.yes,
  ]

  getEntityUrl ({ providerHostname, file, entity }) {
    if (file) {
      return new URL(`${entity}/blob/HEAD/.github/workflows/${file}`, providerHostname).toString()
    }
    return new URL(entity, providerHostname).toString()
  }

  validateEntity (entity) {
    if (entity.split('/').length !== 2) {
      throw new Error(`${this.constructor.providerEntity} must be specified in the format owner/repository`)
    }
  }

  validateFile (file) {
    if (file !== path.basename(file)) {
      throw new Error('GitHub Actions workflow must be just a file not a path')
    }
  }

  static optionsToBody (options) {
    const { file, repository, environment } = options
    const trustConfig = {
      type: 'github',
      claims: {
        repository,
        workflow_ref: {
          file,
        },

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Pass just `owner/repository` (e.g. `npm/cli`).
  2. Strip scheme, host, `.git`, and any trailing path/query before passing.
  3. If you have a full URL, extract the path segments: `new URL(url).pathname.slice(1).replace(/\.git$/, '')`.

Example fix

// before
--repository https://github.com/npm/cli
// after
--repository npm/cli
Defensive patterns

Strategy: validation

Validate before calling

function normalizeEntity(entity) {
  try {
    const u = new URL(entity)
    entity = u.pathname.slice(1)
  } catch { /* not a URL */ }
  const parts = entity.replace(/\.git$/, '').split('/').filter(Boolean)
  if (parts.length !== 2) {
    throw new Error(`GitHub entity must be owner/repository, got "${entity}"`)
  }
  return parts.join('/')
}

Type guard

function isOwnerRepo(entity) {
  return /^[^/\s]+\/[^/\s]+$/.test(String(entity).replace(/\.git$/, ''))
}

Prevention

When it happens

Trigger: `entity.split('/').length !== 2` — e.g. passing a full URL, a scoped path, a single segment, or extra slashes.

Common situations: Passing `https://github.com/owner/repo`, `owner/repo/extra`, `owner` alone, or `@scope/pkg` style values.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/d9f54680520efc08. Report an issue: GitHub.