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

  1. List the instance's configured issue link specs (administration) and use an exact existing name.
  2. Correct the linkName spelling/casing.
  3. 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

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


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