nodejs/node · error · Error
GitLab CI/CD pipeline file must be just a file not a path
Error message
GitLab CI/CD pipeline file must be just a file not a path
What it means
Thrown by GitLab trust provider's validateFile() when the --file value is not equal to its own path.basename, i.e. it contains path separators. GitLab's trusted-publishing claim references a single top-level pipeline filename inside the project, not an arbitrary relative path, so a value like 'ci/pipeline.yml' or './.gitlab-ci.yml' is rejected before optionsToBody builds the ci_config_ref_uri.
Source
Thrown at deps/npm/lib/commands/trust/gitlab.js:65
globalDefinitions.yes,
]
getEntityUrl ({ providerHostname, file, entity }) {
if (file) {
return new URL(`${entity}/-/blob/HEAD/${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 group/project or group/subgroup/project`)
}
}
validateFile (file) {
if (file !== path.basename(file)) {
throw new Error('GitLab CI/CD pipeline file must be just a file not a path')
}
}
static optionsToBody (options) {
const { file, project, environment } = options
const trustConfig = {
type: 'gitlab',
claims: {
project_path: project,
// this looks off, but this is correct
/** The ref path to the top-level pipeline definition, for example, gitlab.example.com/my-group/my-project//.gitlab-ci.yml@refs/heads/main. Introduced in GitLab 16.2. This claim is null unless the pipeline definition is located in the same project. */
ci_config_ref_uri: {
file,
},
...(environment) && { environment },
},
}
return trustConfigView on GitHub (pinned to 1b2de5e052)
Solutions
- Use just the filename, e.g. `--file .gitlab-ci.yml`, and ensure the file sits at the repository root.
- If you genuinely need a nested pipeline file, move/include it at the repo root since GitLab trusted publishing only supports top-level files.
- Strip any './' prefix or directory component before passing the value.
Example fix
// before npm trust gitlab --file ci/.gitlab-ci.yml --project group/proj // after npm trust gitlab --file .gitlab-ci.yml --project group/proj
Defensive patterns
Strategy: validation
Validate before calling
const path = require('node:path')
const assertPipelineFile = (file) => {
if (file !== path.basename(file)) {
throw new TypeError(`Pipeline file must be a bare filename, got: ${file}`)
}
} Type guard
const path = require('node:path')
const isBareFilename = (v) => typeof v === 'string' && v === path.basename(v) Try / catch
try {
await trustGitlab.exec([...])
} catch (err) {
if (/must be just a file/i.test(err.message)) {
// strip the directory component and retry with path.basename(file)
} else { throw err }
} Prevention
- Keep your pipeline definition at the repository root.
- Pass only the filename to --file, never a relative path.
- In scripts, normalize with path.basename() before invoking the command.
When it happens
Trigger: Calling `npm trust gitlab --file ci/.gitlab-ci.yml ...` or `--file ./config/pipeline.yaml`. Also triggered by a leading './' since basename strips it but the raw string differs. validateFile runs after the .yml/.yaml extension check in flagsToOptions.
Common situations: Migrating from a CI setup where the pipeline lives in a subfolder; assuming the flag accepts a path like most CLI file flags; IDE autocomplete inserting a relative path.
Related errors
- ${this.constructor.providerEntity} must be specified in the
- Package name must be specified either as an argument or in t
- Package name must be specified either as an argument or in t
- ID of the trusted relationship to revoke must be specified w
- At least one permission flag is required (--allow-publish, -
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/450d8d7b1d0450fc.
Report an issue: GitHub.