theonedev/onedev · error · NotFoundException
Link spec not found: ${linkName}
Error message
Link spec not found: ${linkName} What it means
Thrown as NotFoundException by linkIssues when linkSpecService.find(linkName) returns null, i.e., no issue link spec with the given name exists in the OneDev instance. Link specs are globally configured named relations like 'is caused by', 'depends on', etc.
Source
Thrown at server-core/src/main/java/io/onedev/server/ai/TodResource.java:723
@Path("/link-issues")
@GET
public Map<String, Object> linkIssues(
@QueryParam("currentProject") @NotNull String currentProjectPath,
@QueryParam("sourceReference") @NotNull String sourceReference,
@QueryParam("linkName") @Nullable String linkName,
@QueryParam("targetReference") @NotNull String targetReference) {
if (SecurityUtils.getUser() == null)
throw new UnauthenticatedException();
var currentProject = getProject(currentProjectPath);
var sourceIssue = getIssue(currentProject, sourceReference);
var targetIssue = getIssue(currentProject, targetReference);
var linkSpec = linkSpecService.find(linkName);
if (linkSpec == null)
throw new NotFoundException("Link spec not found: " + linkName);
if (!SecurityUtils.canEditIssueLink(sourceIssue.getProject(), linkSpec)
|| !SecurityUtils.canEditIssueLink(targetIssue.getProject(), linkSpec)) {
throw new UnauthorizedException("No permission to add specified link for specified issues");
}
var link = new IssueLink();
link.setSpec(linkSpec);
if (linkName.equals(linkSpec.getName())) {
link.setSource(sourceIssue);
link.setTarget(targetIssue);
} else {
link.setSource(targetIssue);
link.setTarget(sourceIssue);
}
link.validate();
issueLinkService.create(link);
var linkMap = new HashMap<String, Object>();View on GitHub (pinned to d44925c47c)
Solutions
- List the instance's configured issue link specs (administration) and use an exact existing name.
- Correct the linkName spelling/casing.
- Create the missing link spec in server settings if genuinely needed.
Example fix
// before GET /~api/tod/link-issues?...&linkName=blocks // spec doesn't exist // after GET /~api/tod/link-issues?...&linkName=is blocked by // exact configured spec name
Defensive patterns
Strategy: validation
Validate before calling
const specNames = await getIssueLinkSpecs(); // configured link specs
if (!specNames.includes(linkName)) {
throw new Error(`linkName '${linkName}' is not a configured link spec`);
} Type guard
function isKnownLinkSpec(name, specs) {
return specs.some(s => s.name === name);
} Try / catch
try {
await linkIssues(...);
} catch (e) {
if (e.status === 404 || /Link spec not found/.test(e.message)) {
// refresh the link spec list and retry with a valid name
} else throw e;
} Prevention
- Fetch configured link specs rather than hardcoding names.
- Watch for admin renames/deletions of link specs.
- Keep per-environment link spec names in configuration, not code.
When it happens
Trigger: Passing a linkName query parameter that does not match any configured issue link spec (typo, renamed/deleted spec, wrong casing).
Common situations: Link spec renamed by an admin after the AI workflow was built; agent invents a link name; instance-specific link specs differ between environments.
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
- Iteration '${iterationName}' not found
- Pull request not found:
- Not found
- Unable to find project to import build spec: {0}
- Job not found (
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/222de7f07b1ce728.
Report an issue: GitHub.