{"record":{"id":"70e7a317688304ba","repo":"theonedev/onedev","slug":"cannot-link-to-self","errorCode":null,"errorMessage":"Cannot link to self","messagePattern":"Cannot link to self","errorType":"validation","errorClass":"ValidationException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/model/IssueLink.java","lineNumber":87,"sourceCode":"\tpublic void setSpec(LinkSpec spec) {\n\t\tthis.spec = spec;\n\t}\n\t\n\tpublic Issue getLinked(Issue issue) {\n\t\treturn issue.equals(source)?target:source;\n\t}\n\n\tpublic int getPosition() {\n\t\treturn position;\n\t}\n\n\tpublic void setPosition(int position) {\n\t\tthis.position = position;\n\t}\n\n\tpublic void validate() {\n\t\tif (getSource().equals(getTarget()))\n\t\t\tthrow new ValidationException(\"Cannot link to self\");\n\t\tif (getSpec().getOpposite() != null) {\n\t\t\tif (getSource().getTargetLinks().stream()\n\t\t\t\t\t.anyMatch(it -> it.getSpec().equals(getSpec()) && it.getTarget().equals(getTarget())))\n\t\t\t\tthrow new ValidationException(\"Source issue already linked to target issue via specified link spec\");\n\t\t\tif (!getSpec().isMultiple()\n\t\t\t\t\t&& getSource().getTargetLinks().stream().anyMatch(it -> it.getSpec().equals(getSpec())))\n\t\t\t\tthrow new ValidationException(\n\t\t\t\t\t\t\"Link spec is not multiple and the source issue is already linked to another issue via this link spec\");\n\t\t\tif (!getSpec().getParsedIssueQuery(getSource().getProject()).matches(getTarget()))\n\t\t\t\tthrow new ValidationException(\"Link spec not allowed to link to the target issue\");\n\t\t\tif (!getSpec().getOpposite().isMultiple()\n\t\t\t\t\t&& getTarget().getSourceLinks().stream().anyMatch(it -> it.getSpec().equals(getSpec())))\n\t\t\t\tthrow new ValidationException(\n\t\t\t\t\t\t\"Opposite side of link spec is not multiple and the target issue is already linked to another issue via this link spec\");\n\t\t\tif (!getSpec().getOpposite().getParsedIssueQuery(getSource().getProject())\n\t\t\t\t\t.matches(getSource()))\n\t\t\t\tthrow new ValidationException(\"Opposite side of link spec not allowed to link to the source issue\");\n\t\t} else {","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/model/IssueLink.java#L69-L105","documentation":"Domain validation in IssueLink.validate: source and target issues are the same issue, which a self-link cannot represent (getLinked would be ambiguous); ValidationException is raised. Called from createLink, so the invalid link is rejected before persistence. Fix: link two distinct issues.","triggerScenarios":"Creating an issue link (via UI, API, or createLink) where source issue equals target issue, e.g. passing the same issue id for both ends.","commonSituations":"Automation scripts computing the link target incorrectly (off-by-one/wrong variable); UI bugs allowing self-selection; bulk import scripts linking an issue to itself; copy-paste of issue numbers.","solutions":["Ensure the target issue id differs from the source issue id before calling createLink","Guard scripts: skip linking when source.getId() == target.getId()","Fix import/bulk data so self-references are removed"],"exampleFix":"// before\nissueLinkService.createLink(issue, issue, spec);  // self link\n// after\nif (!target.equals(issue)) issueLinkService.createLink(issue, target, spec);","handlingStrategy":"validation","validationCode":"if (source.equals(target)) { /* skip or reject link */ }","typeGuard":null,"tryCatchPattern":"try { issueLinkService.createLink(source, target, spec); } catch (ValidationException e) { log.warn(\"Link rejected: \" + e.getMessage()); }","preventionTips":["Guard against self-links in scripts and imports","Validate source != target before any createLink call","Test automation with edge-case issue ids"],"tags":["issues","validation","links"],"backgroundTag":"invalid-state-transition","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"}