# Bugfix — Issue #1686: `reqTreeReorder.html` — "Back to specification management" was a dead self-reload in the error state and pointed at the wrong screen otherwise
**Number:** #1686
**Status:** Fixed (verified — the fix was already in the default branch; this run pinned it with a regression suite and closed the issue)
**Component:** `gui/templates/requirements/reqTreeReorder.html`
**Area:** Requirements / Specification Tree Reordering
**Fixing commit (code):** `983c9179c` — *fix(reqtreereorder): back link was a dead self-reload on the error path (Refs #1681)*
**Verification commit (this run):** `6588d4a18`
## Symptom
Two defects in one control.
1. **In the error / no-rights state the link pointed at itself.** The markup shipped
`href="#"` and the only code that set a real target ran inside the **success** handler of
the `init` AJAX call. On the 403 path ("You are not authorized to view requirements") the
href was never written, so the *Back to specification management* button reloaded the
forbidden page in the same tab. The observed URL was literally the current page with a
trailing `#`.
2. **With data loaded the label lied.** When a specification was selected the link was pointed
at `reqSpecView.html` (the specification **viewer**) while the label said
*Back to specification **management***, leaving the management screen unreachable from the
toolbar.
`target="_blank"` additionally made a *back* link open a new tab, unlike the sibling
`#mgmtLink` in `reqSpecView.html`.
## Root cause
The root cause is a design error, not a typo: **the href of a navigation control was
produced as a side effect of a successful data load.** A static `.html` template cannot
server-render the id (it is not PHP), so the assignment was placed in the AJAX `success`
handler — which means the control is broken in exactly the state where the user most needs
an escape hatch (403/404).
Root cause chain, as originally shipped:
| Hop | Location | What was wrong |
|---|---|---|
| 1 | `reqTreeReorder.html` (markup) | `` — `#` is "same document", i.e. a self-reload; `target="_blank"` opens a *back* link in a new tab. |
| 2 | the only assignment, inside the `success:` handler of `$.ajax(...)` in `load()` | The href was never written when the call failed → the 403/404 dead end kept `href="#"`. |
| 3 | same success handler | On success it rewrote the href to `reqSpecView.html?id=&tproject_id=` — the viewer — contradicting the "management" label. |
### Why the issue stayed open
Both defects were fixed by the #1681 modernization run in commit `983c9179c`, an ancestor of
the default branch. The implementing run left the issue **OPEN** (its own body documents the
fix under *"Fix applied in the Refs #1681 branch"*), so triage kept surfacing it as the oldest
open bug. Nothing was lost in the code; what was lost was the closure step. This run verified
the fix, pinned it with a regression suite and closed the issue.
## Fix (already in the default branch — shape of the correct solution)
* **markup `:77`** — the href is now a real page in the static markup,
`href="/gui/templates/requirements/reqSpecMgmt.html"`, and `target="_blank"` is gone.
* **`:181-186` `buildBackLink()`** — derives the target **synchronously from the URL query
string**, with a comment stating the intent ("the escape hatch must work on the error path").
* **`:189`** — `buildBackLink()` runs on DOM-ready, **before** `TLi18n.load()` and before
`load(false)` → before any `$.ajax`. This is the structural guarantee: the href no longer
depends on an API response. The `:0` branch still yields a valid management-screen URL,
never `'#'`; the rewrite is only a *refinement* that adds `tproject_id`.
* **`:196-199` + `:417-424`** — the dropped "open this specification" target was **not** lost:
it moved to the spec document chip in the Context card, whose `data-href` points at
`reqSpecView.html?id=&tproject_id=` and opens in a new tab.
### Alternatives rejected
1. *Touch the file to have a diff* — rejected: the code is already correct and verified;
any edit is churn and risks re-introducing the defect being certified.
2. *Make the fallback project-aware without `tproject_id`* — rejected: both entry points
(`reqSpecMgmt.html:954`, `:964`) always pass it, and the target degrades gracefully
without it (renders `Test Project: -`, API answers a clean `400`, no fatal).
3. *Harden `reqSpecMgmt.html` against `tproject_id=0`* — out of scope, it already degrades
cleanly.
## Verification (measured, 9/9 cases PASS)
| Case | Measured result |
|---|---|
| Static markup, **before any JS runs** (`curl` + `grep -o 'id="backLink"[^>]*'`) | `id="backLink" href="/gui/templates/requirements/reqSpecMgmt.html"` — a real destination, so the link survives a total JS failure |
| `target="_blank"` on the back link | `grep -c _blank` → `0` |
| Error / 404 state | `href=/gui/templates/requirements/reqSpecMgmt.html?tproject_id=13`, `target=null`, `applyDisabled=true`, drag hint hidden — never a self-reload |
| Success state | `href_points_at_viewer:false`, `rows=2`, `rowsDraggable=["true","true"]` — the href matches its label |
| Real `.click()` on the back link | navigated **in place** to `…/reqSpecMgmt.html?tproject_id=13`, same tab |
| Spec chip click (`tproject_id=14`, spec 17) | new page opened at `reqSpecView.html?id=17&tproject_id=14` — the viewer target survived |
| Second test project | `href=…reqSpecMgmt.html?tproject_id=14`, `uses_wrong_project:false` — `tproject_id` follows the URL, never hardcoded |
| No project in context | `href=/gui/templates/requirements/reqSpecMgmt.html`, *"No test project in context."*, target renders `Test Project: -`, API `400` — no fatal, no blank page |
| Event Viewer / `events` | 1 row total, the login audit (`log_level=16`, `audit_login_succeeded`) — **zero** Error/Warning rows |
Regression suite: `## Regression — Issue #1686` in `tmp/TLU_Test_Cases.md`
(cases `TC-1686-01..09`). Merge-base gate
`TLU_REQUIRE_SUITE="Issue #1686" bash ai/verify_test_suites.sh` → **7 PASS / 0 FAIL**
(suite headings 65 → 66, nothing lost).
## Screenshot
## Files changed
* This run: `tmp/TLU_Test_Cases.md` (append-only regression suite), `docs/Bugfix-Issue-1686-reqtreereorder-Back-Link-Dead-Self-Reload.md`, wiki mirror + screenshot.
* No production code change in this run — the code fix is `983c9179c`.
## Commits
* `983c9179c` — the actual code fix (Refs #1681), already on the default branch
* `6588d4a18` — regression suite for this run
* docs + wiki mirror commit for this run
## Reference
See also: [Reorder Requirements Tree (reqTreeReorder) Modernized](Reorder-Requirements-Tree-Modernized.md)
and [Bugfix #1685 — drag & drop dirty flag](Bugfix-Issue-1685-reqtreereorder-Drag-Drop-Dirty-Flag.md).
Sibling issues from the same #1681 browser-testing pass, all in the same screen, all verified
fixed in the default branch and covered by the same fixture set:
[#1687](https://github.com/sebiboga/testlink-upgraded/issues/1687) (hardcoded `-` "Modified by" tile),
[#1688](https://github.com/sebiboga/testlink-upgraded/issues/1688) (toolbar stayed live on the 403/404 page),
[#1689](https://github.com/sebiboga/testlink-upgraded/issues/1689) (rows draggable in read-only mode),
[#1690](https://github.com/sebiboga/testlink-upgraded/issues/1690) (hardcoded `tproject_id` in the back link).