{"record":{"id":"e020b771300d5e35","repo":"nodejs/node","slug":"providerfile-must-end-in-yml-or-yaml","errorCode":null,"errorMessage":"${providerFile} must end in .yml or .yaml","messagePattern":"(.+?) must end in \\.yml or \\.yaml","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"deps/npm/lib/trust-cmd.js","lineNumber":280,"sourceCode":"      entity = flags[entityKey]\n      entitySource = 'flag'\n    } else if (!invalidPkgJsonProviderType && git?.repository) {\n      entity = git.repository\n      entitySource = 'package.json'\n    }\n    const mismatchPkgJsonRepository = matchPkg && git && entity !== git.repository\n    const usedRepositoryInPkgJson = entitySource === 'package.json'\n\n    const warnings = []\n    if (!pkgName) {\n      throw new Error('Package name must be specified either as an argument or in package.json file')\n    }\n\n    if (!flags.file) {\n      throw new Error(`${providerFile} must be specified with the file option`)\n    }\n    if (!flags.file.endsWith('.yml') && !flags.file.endsWith('.yaml')) {\n      throw new Error(`${providerFile} must end in .yml or .yaml`)\n    }\n\n    this.validateFile?.(flags.file)\n\n    if (invalidPkgJsonProviderType) {\n      const message = this.warnString`Repository in package.json is not a ${providerEntity}`\n      if (!flags[entityKey]) {\n        throw new Error(message)\n      } else {\n        warnings.push(message)\n      }\n    } else {\n      if (mismatchPkgJsonRepository) {\n        warnings.push(this.warnString`Repository in package.json (${git.repository}) differs from provided ${providerEntity} (${entity})`)\n      }\n    }\n\n    if (!entity && matchPkg) {","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/npm/lib/trust-cmd.js#L262-L298","documentation":"Thrown by TrustCommand.flagsToOptions when `--file` exists but does not end in `.yml` or `.yaml`. Trusted-publishing claims reference a YAML pipeline definition, so a JSON, txt, or extensionless file is rejected. The check is a simple two-call endsWith OR.","triggerScenarios":"Passing `--file .gitlab-ci.json`, `--file Dockerfile`, `--file Makefile`, or a typo like `--file .gitlab-ci.yml.bak`. Fires immediately after the file-presence check, before provider-specific validateFile.","commonSituations":"Migrating from JSON-based config; wrong extension from a template generator; trailing characters from copy-paste.","solutions":["Use a `.yml` or `.yaml` file: rename or convert your pipeline config.","Check for typos and stray suffixes (e.g. .yml.bak, .yaml~).","If your pipeline truly is JSON, wrap it in a YAML file that includes it via GitLab's `include` (the top-level claim still must be YAML)."],"exampleFix":"// before\nnpm trust gitlab --file pipeline.json --project g/p --allow-publish\n// after\nnpm trust gitlab --file .gitlab-ci.yml --project g/p --allow-publish","handlingStrategy":"validation","validationCode":"if (!/\\.(yml|yaml)$/.test(flags.file || '')) {\n  throw new Error(`--file must end in .yml or .yaml, got: ${flags.file}`)\n}","typeGuard":"const isYamlFile = (file) =>\n  typeof file === 'string' && /\\.(yml|yaml)$/.test(file)","tryCatchPattern":"try {\n  await createConfigCommand(...)\n} catch (err) {\n  if (/must end in .yml or .yaml/i.test(err.message)) {\n    // rename/convert the file to YAML, update flags.file, retry\n  } else { throw err }\n}","preventionTips":["Author CI pipeline definitions in YAML from the start.","Validate the file extension in your wrapper script.","Watch for stray suffixes from editor backups (.bak, ~)."],"tags":["validation","trust","cli-args","yaml"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}