{"record":{"id":"30c6d8d419378eb6","repo":"yarnpkg/yarn","slug":"publishfail","errorCode":null,"errorMessage":"publishFail","messagePattern":"publishFail","errorType":"exception","errorClass":"MessageError","httpStatus":null,"severity":"error","filePath":"src/cli/commands/publish.js","lineNumber":119,"sourceCode":"  };\n\n  pkg._id = `${pkg.name}@${pkg.version}`;\n  pkg.dist = pkg.dist || {};\n  pkg.dist.shasum = crypto.createHash('sha1').update(buffer).digest('hex');\n  pkg.dist.integrity = ssri.fromData(buffer).toString();\n\n  const registry = String(config.getOption('registry'));\n  pkg.dist.tarball = url.resolve(registry, tbURI).replace(/^https:\\/\\//, 'http://');\n\n  // publish package\n  try {\n    await config.registries.npm.request(NpmRegistry.escapeName(pkg.name), {\n      registry: pkg && pkg.publishConfig && pkg.publishConfig.registry,\n      method: 'PUT',\n      body: root,\n    });\n  } catch (error) {\n    throw new MessageError(config.reporter.lang('publishFail', error.message));\n  }\n\n  await config.executeLifecycleScript('publish');\n  await config.executeLifecycleScript('postpublish');\n}\n\nexport async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {\n  // validate arguments\n  const dir = args[0] ? path.resolve(config.cwd, args[0]) : config.cwd;\n  if (args.length > 1) {\n    throw new MessageError(reporter.lang('tooManyArguments', 1));\n  }\n  if (!await fs.exists(dir)) {\n    throw new MessageError(reporter.lang('unknownFolderOrTarball'));\n  }\n\n  const stat = await fs.lstat(dir);\n  let publishPath = dir;","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/yarnpkg/yarn/blob/c2dda503f3759b5be5f0e24ecd9cf5c97a540147/src/cli/commands/publish.js#L101-L137","documentation":"The actual PUT to the registry (publish.js:111-117) is wrapped in try/catch; any failure—network error, 4xx/5xx response, conflict, forbidden, payment required—is re-thrown as publishFail with the underlying error.message. So this error signals the HTTP publish itself failed, and the wrapped message carries the registry's reason.","triggerScenarios":"Re-publishing an existing version (409/EPUBLISHCONFLICT); not authenticated / no publish rights (403); scoped package needing --access on first publish; registry rate-limit or outage (5xx); offline/network break.","commonSituations":"Forgot to bump version before publishing; npm token lacks publish scope; first publish of a scoped package without `--access public`; corporate registry misconfiguration; transient network failures.","solutions":["Read the wrapped message: 'EPUBLISHCONFLICT' / version exists → bump the version (e.g., `yarn version`) and retry.","403 / forbidden → verify your token has publish rights for the package scope and that you are logged in (`yarn login`).","First publish of a scoped package → pass `--access public` (or set publishConfig.access).","Network/5xx → wait and retry; confirm registry reachability with `curl -I <registry>`."],"exampleFix":"# before — version 1.0.0 already on registry\n$ yarn publish   # publishFail: EPUBLISHCONFLICT\n# after\n$ yarn version --new-version patch\n$ yarn publish","handlingStrategy":"retry","validationCode":"async function isVersionPublished(registry, name, version) {\n  const res = await fetch(`${registry}/${name}`);\n  if (!res.ok) return false;\n  const meta = await res.json();\n  return Boolean(meta.versions && meta.versions[version]);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await runYarn(['publish']);\n} catch (e) {\n  if (/publishFail/.test(e.message)) {\n    const m = e.message;\n    if (/EPUBLISHCONFLICT|already exists/i.test(m)) console.error('Bump the version first.');\n    else if (/403|forbidden/i.test(m)) console.error('Token lacks publish rights.');\n    else console.error('Transient publish failure; retry.');\n    return;\n  }\n  throw e;\n}","preventionTips":["Bump the version on every publish (automate with `yarn version`).","Verify publish rights and a valid token before releasing.","For scoped first publishes, set `--access public` or publishConfig.access.","Retry transient 5xx/network failures with backoff."],"tags":["cli","publish","registry","network","version-conflict"],"backgroundTag":null,"analyzedSha":"c2dda503f3759b5be5f0e24ecd9cf5c97a540147","analyzedAt":"2026-08-13T04:17:06.305Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}