{"record":{"id":"601346b4909b3eee","repo":"pcottle/learnGitBranching","slug":"tags-are-not-allowed-as-sources-for-pushing","errorCode":null,"errorMessage":"Tags are not allowed as sources for pushing","messagePattern":"Tags are not allowed as sources for pushing","errorType":"validation","errorClass":"GitError","httpStatus":null,"severity":"error","filePath":"src/js/git/index.js","lineNumber":1139,"sourceCode":"  }\n  return inOrder;\n};\n\nGitEngine.prototype.push = function(options) {\n  options = options || {};\n\n  if (options.source === \"\") {\n    // delete case\n    this.pushDeleteRemoteBranch(\n      this.refs[ORIGIN_PREFIX + options.destination],\n      this.origin.refs[options.destination]\n    );\n    return;\n  }\n\n  var sourceBranch = this.resolveID(options.source);\n  if (sourceBranch && sourceBranch.attributes.type === 'tag') {\n    throw new GitError({\n      msg: intl.todo('Tags are not allowed as sources for pushing'),\n    });\n  }\n\n  if (!this.origin.doesRefExist(options.destination)) {\n    console.warn('ref', options.destination);\n    this.makeBranchOnOriginAndTrack(\n      options.destination,\n      this.getCommitFromRef(sourceBranch)\n    );\n    // play an animation now since we might not have to fast forward\n    // anything... this is weird because we are punting an animation\n    // and not resolving the promise but whatever\n    this.animationFactory.playRefreshAnimation(this.origin.gitVisuals);\n    this.animationFactory.playRefreshAnimation(this.gitVisuals);\n  }\n  var branchOnRemote = this.origin.resolveID(options.destination);\n  var sourceLocation = this.resolveID(options.source || 'HEAD');","sourceCodeStart":1121,"sourceCodeEnd":1157,"githubUrl":"https://github.com/pcottle/learnGitBranching/blob/5b09d0ff9678cad164f5a7488a279a44f90d7256/src/js/git/index.js#L1121-L1157","documentation":"git push does not accept a tag as the source ref; this engine models that by rejecting any options.source that resolves to a ref of type 'tag'. Real git likewise requires pushing tags via explicit refspecs like refs/tags/x.","triggerScenarios":"Calling the push API (or typing git push) where options.source resolves through resolveID to a ref with attributes.type === 'tag', e.g. git push origin v1.","commonSituations":"Trying to push a tag with branch syntax; level scripts that mistakenly use a tag name as a source.","solutions":["Use the tag push syntax/refspec (git push origin v1 is rejected; use the dedicated tag push path or refs/tags/v1)","Delete/recreate the ref as a branch if you meant a branch","Check resolveID(options.source).attributes.type before pushing"],"exampleFix":"// before\ngit push origin v1\n// after\ngit push origin refs/tags/v1","handlingStrategy":"type-guard","validationCode":"var src = engine.resolveID(options.source);\nif (src && src.attributes.type === 'tag') throw new Error('use refs/tags/ refspec');","typeGuard":"function isTagRef(engine, id) {\n  var r = engine.resolveID(id);\n  return !!r && r.attributes && r.attributes.type === 'tag';\n}","tryCatchPattern":null,"preventionTips":["Never use bare tag names as push sources","Push tags via explicit tag refspecs"],"tags":["git","push","tag","ref-validation"],"backgroundTag":"git-invalid-refspec-source","analyzedSha":"5b09d0ff9678cad164f5a7488a279a44f90d7256","analyzedAt":"2026-08-27T13:53:49.057Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}