theonedev/onedev · error · NotFoundException

Tag not found: ${tagName}

Error message

Tag not found: ${tagName}

What it means

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.

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/RepositoryResource.java:216

				.map(it-> GitUtils.ref2tag(it.getName()))
				.collect(toList());
	}
	
	@Api(order=60, description="Get specified tag")
	@Path("/{projectId}/tags/{tag:.*}")
	@GET
	public RefResponse getTag(
			@PathParam("projectId") Long projectId, 
			@PathParam("tag") @Api(example="test-tag") String tagName) {
		Project project = projectService.load(projectId);
		
		if (!SecurityUtils.canReadCode(project)) {
			throw new UnauthorizedException();
		}

		RefFacade ref = project.getTagRef(tagName);
		if (ref == null)
			throw new NotFoundException("Tag not found: " + tagName);

		RefResponse response = new RefResponse();
		
		response.refName = ref.getName();
		response.commitHash = project.getRevCommit(ref.getObjectId(), true).getName();
		
		return response;
	}
	
	@Api(order=70, description="Create a new tag")
	@Path("/{projectId}/tags")
	@POST
	public Response createTag(@PathParam("projectId") Long projectId, @NotNull CreateTagRequest request) {
		Project project = projectService.load(projectId);
		if (!SecurityUtils.canCreateTag(project, request.getTagName())) {
			throw new UnauthorizedException();
		}

View on GitHub (pinned to d44925c47c)

Solutions

  1. List existing tags via GET /~api/{projectId}/tags and use an exact name
  2. Create the tag via POST /~api/{projectId}/tags if missing
  3. Pass the short tag name without the 'refs/tags/' prefix
  4. Fix casing to match the existing tag

Example fix

// before
GET /~api/1/tags/1.0.0 // actual tag is v1.0.0
// after
GET /~api/1/tags/v1.0.0
Defensive patterns

Strategy: try-catch

Validate before calling

const tags = (await api.get(`/projects/${id}/tags`)).data;
if (!tags.includes(tagName)) throw new Error(`tag ${tagName} does not exist`);

Try / catch

try {
  const tag = await getTag(projectId, tagName);
} catch (NotFoundException e) {
  // fall back to listing tags or creating the tag
}

Prevention

When it happens

Trigger: 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/').

Common situations: 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.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/75a4c0546e43a7c4. Report an issue: GitHub.