theonedev/onedev · error · NotFoundException

Unable to find issue

Error message

Unable to find issue: ${value}

What it means

QueryUtils.getIssue resolves an issue reference (e.g. '#123' or 'project#123') to an Issue entity via IssueService.find. If no issue with that number exists in the referenced project, a NotFoundException 'Unable to find issue' is thrown. Found issues are resolved through moved-to chains before being returned.

Solutions

  1. Verify the issue number exists in the referenced project (check the issue URL)
  2. Add the project scope to the reference (e.g. 'group/project#123') or pass the correct default Project
  3. Check whether the issue was deleted or moved — getIssue follows moved-to chains, so use the new number if the original was removed
  4. Confirm the calling user can access the project containing the issue

Example fix

// before
Issue issue = QueryUtils.getIssue(null, "#42");
// after
Issue issue = QueryUtils.getIssue(project, "group/my-project#42");
Defensive patterns

Strategy: try-catch

Validate before calling

if (!value.matches("(#\\d+|[^#]+#\\d+)"))
    throw new UserException("Issue reference must look like '#123' or 'project#123'");

Type guard

boolean isIssueReference(String s) {
    return s != null && s.matches("(#\\d+|[^#]+#\\d+)");
}

Try / catch

try {
    Issue issue = QueryUtils.getIssue(project, value);
} catch (NotFoundException e) {
    logger.warn("Issue not found: {}", value);
    // skip this criterion value or notify the user
}

Prevention

When it happens

Trigger: Calling QueryUtils.getIssue with an issue number that does not exist in the target project; referencing '#123' without a project scope when project is null; referencing an issue in a different project than intended.

Common situations: Query criteria values like 'state is Open and number is #999' after issues were deleted; copied issue links from another project; issues in private projects invisible to the caller; typo in the issue number.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at server-core/src/main/java/io/onedev/server/util/QueryUtils.java:152

	public static ProjectScopedRevision getRevision(@Nullable Project project, String value) {
		if (project != null && !value.contains(":"))
			value = project.getPath() + ":" + value;
		ProjectScopedRevision revision = ProjectScopedRevision.from(value);
		if (revision != null)
			return revision;
		else
			throw new NotFoundException("Unable to find revision: " + value);
	}
	
	public static Issue getIssue(@Nullable Project project, String value) {
		var reference = IssueReference.of(value, project);
		var issueService = OneDev.getInstance(IssueService.class);
		var issue = issueService.find(reference.getProject(), reference.getNumber());
		if (issue != null)
			return issue.resolveMovedTo();
		else
			throw new NotFoundException("Unable to find issue: " + value);
	}
	
	public static PullRequest getPullRequest(@Nullable Project project, String value) {
		var reference = PullRequestReference.of(value, project);
		var pullRequest = OneDev.getInstance(PullRequestService.class).find(reference.getProject(), reference.getNumber());
		if (pullRequest != null)
			return pullRequest;
		else
			throw new NotFoundException("Unable to find pull request: " + value);
	}
	
	public static Build getBuild(@Nullable Project project, String value) {
		var reference = BuildReference.of(value, project);
		var build = OneDev.getInstance(BuildService.class).find(reference.getProject(), reference.getNumber());
		if (build != null)
			return build;
		else
			throw new NotFoundException("Unable to find build: " + value);

View on GitHub (pinned to d44925c47c)