{"record":{"id":"75a4c0546e43a7c4","repo":"theonedev/onedev","slug":"tag-not-found-tagname","errorCode":null,"errorMessage":"Tag not found: ${tagName}","messagePattern":"Tag not found: (.+?)","errorType":"http","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/RepositoryResource.java","lineNumber":216,"sourceCode":"\t\t\t\t.map(it-> GitUtils.ref2tag(it.getName()))\n\t\t\t\t.collect(toList());\n\t}\n\t\n\t@Api(order=60, description=\"Get specified tag\")\n\t@Path(\"/{projectId}/tags/{tag:.*}\")\n\t@GET\n\tpublic RefResponse getTag(\n\t\t\t@PathParam(\"projectId\") Long projectId, \n\t\t\t@PathParam(\"tag\") @Api(example=\"test-tag\") String tagName) {\n\t\tProject project = projectService.load(projectId);\n\t\t\n\t\tif (!SecurityUtils.canReadCode(project)) {\n\t\t\tthrow new UnauthorizedException();\n\t\t}\n\n\t\tRefFacade ref = project.getTagRef(tagName);\n\t\tif (ref == null)\n\t\t\tthrow new NotFoundException(\"Tag not found: \" + tagName);\n\n\t\tRefResponse response = new RefResponse();\n\t\t\n\t\tresponse.refName = ref.getName();\n\t\tresponse.commitHash = project.getRevCommit(ref.getObjectId(), true).getName();\n\t\t\n\t\treturn response;\n\t}\n\t\n\t@Api(order=70, description=\"Create a new tag\")\n\t@Path(\"/{projectId}/tags\")\n\t@POST\n\tpublic Response createTag(@PathParam(\"projectId\") Long projectId, @NotNull CreateTagRequest request) {\n\t\tProject project = projectService.load(projectId);\n\t\tif (!SecurityUtils.canCreateTag(project, request.getTagName())) {\n\t\t\tthrow new UnauthorizedException();\n\t\t}\n","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/RepositoryResource.java#L198-L234","documentation":"REST lookup in RepositoryResource.getTag: the tag name path parameter does not match any tag ref in the project repository (project.getTagRef returned null), so NotFoundException is returned to the API caller. Fix: use an existing tag name, or create/push the tag first.","triggerScenarios":"Calling GET /~api/{projectId}/tags/{tagName} with a tag that was never created, was deleted, or whose name doesn't match exactly (case, prefix like 'v', or including 'refs/tags/').","commonSituations":"Typo in tag name; assuming a tag exists because a release pipeline was supposed to create it; shallow/empty mirror repos; passing full ref name instead of short tag name.","solutions":["List existing tags via GET /~api/{projectId}/tags and use an exact name","Create the tag via POST /~api/{projectId}/tags if missing","Pass the short tag name without the 'refs/tags/' prefix","Fix casing to match the existing tag"],"exampleFix":"// before\nGET /~api/1/tags/1.0.0 // actual tag is v1.0.0\n// after\nGET /~api/1/tags/v1.0.0","handlingStrategy":"try-catch","validationCode":"const tags = (await api.get(`/projects/${id}/tags`)).data;\nif (!tags.includes(tagName)) throw new Error(`tag ${tagName} does not exist`);","typeGuard":null,"tryCatchPattern":"try {\n  const tag = await getTag(projectId, tagName);\n} catch (NotFoundException e) {\n  // fall back to listing tags or creating the tag\n}","preventionTips":["List tags before fetching a specific one","Use exact short tag names (no refs/tags/ prefix)","Verify release pipeline actually created the tag"],"tags":["rest","git","tags","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}