Repository navigation
Bugfix Issue 1859 tcEdit NoActiveVersion 500
Bugfix #1859 — tcEdit.php:327 key(get_last_active_version()) fatal (HTTP 500) for a test case with no active version
The legacy controller lib/testcases/tcEdit.php answered HTTP 500 with an empty body — uncaught PHP 8 TypeError — for any deep link that reaches it without an explicit tcversion_id when the target test case has no active version (all tcversions.active = 0), or when the tcase_id does not exist. The fatal came from init_args() at tcEdit.php:327, which runs on every request before any action dispatch, and wrote no row into the Event Viewer (events table) — only the server error log got a line.
Fixture tmp/fixtures_1859.php: tproject TC Edit 1859, one suite, TC1859-NOACTIVE (its only version deactivated via UPDATE tcversions SET active=0) and TC1859-ACTIVE (control). Admin session via cookie jar.
| URL | Result |
|---|---|
tcEdit.php?tcase_id=<no-active> |
500, 0 bytes — key(): Argument #1 ($array) must be of type array, null given in lib/testcases/tcEdit.php:327
|
tcEdit.php?edit_tc=1&tcase_id=<no-active> |
500, 0 bytes — same |
tcEdit.php?tcase_id=999999 (absent id) |
500, 0 bytes — same |
tcEdit.php?edit_tc=1&tcase_id=<active> (control) |
200, editor renders — unchanged |
After the fix, the first two rows answer 200 and the edit link renders the (inactive) version normally:

lib/functions/testcase.class.php:6182 get_last_active_version() joins tcversions … AND TCV.active = 1; with no active row the result set is empty, and lib/functions/database.class.php:666 fetchRowsIntoMap() returns its initial $items = null for a 0-row result → the method returns null. key(null) is a PHP 8.3 TypeError. The line is dead code inherited from upstream TestLink ($nu was assigned since upstream 1.9.18 and never read — git log -L 325,330), so leaving tcversion_id = 0 (which downstream treats as testcase::ALL_VERSIONS, testcase.class.php:31) is the correct, behaviour-preserving outcome.
Minimal guard at lib/testcases/tcEdit.php:325-331, the same null-guard family already applied for this exact defect elsewhere: (array) casts at requirement_spec_mgr.class.php:2639 / :2763 (#1705, #1708), is_null() guards at specview.php:871 and xmlrpc.class.php:6461; is_array() matches the precedent at api/reqtcassign/index.php:438. (Related open issue: #1858.)
if( $args->tcversion_id == 0 && $args->tcase_id > 0 ) {
// get latest active version
// get_last_active_version() returns NULL when the test case has no active
// version (or does not exist) -> key() would throw a PHP 8 TypeError (#1859)
$lastActiveVersion = $tcaseMgr->get_last_active_version($args->tcase_id);
$nu = is_array($lastActiveVersion) ? key($lastActiveVersion) : null;
}Alternatives rejected: key((array)$…) cast only — equivalent but less explicit about the null case; setting $args->tcversion_id = $nu — behaviour change ($nu is dead since 1.9.18; 0 is the ALL_VERSIONS sentinel); an error/redirect for the no-active state — the control URL has never fataled, so parity (HTTP 200) is the correct expectation.
| Case | Before | After |
|---|---|---|
?tcase_id=<no-active> |
500, 0 bytes | 200 |
?edit_tc=1&tcase_id=<no-active> |
500, 0 bytes | 200, editor renders the test case |
?tcase_id=999999 (absent) |
500, 0 bytes | 200 |
control ?edit_tc=1&tcase_id=<active>
|
200 | unchanged (200) |
| deactivate-last-version → edit | fatal | 200, renders |
events table / server log |
fatal lines only | no new Error; only the 4 documented #1863 warnings for the absent-id case |
Test-suite gate: TLU_REQUIRE_SUITE="Issue #1859" bash ai/verify_test_suites.sh → exit 0 (no suite lost vs the merge base).
-
#1860 — activate/deactivate/create-version flows answer 500 from a Smarty Compiler error in
gui/templates/dashio/include/attachments.inc.tpl:106. -
#1861 —
requirement_mgr.class.php:1119current()of a nullget_last_active_version()(reachable from the BFFPOST /assign-reqs). -
#1862 —
testcase.class.php:5105count()fatal when the edit action is used for an absenttcase_id. -
#1863 — 4
E_WARNING "Undefined array key 0..3"per absent-id load, from thebuildDirectWebLink()list()destructure (testcase.class.php:5700). -
#1864 —
testcase::addRelation()(testcase.class.php:8199-8200, found in post-fix review): when the source test case has no active version,get_last_active_version()returns null,intval(null)=0is written intotestcase_relations.source_id— verified: returnsstatus_ok=true+ bad row(source_id=0, destination_id=53)+ 2E_WARNINGrows inevents.
-
lib/testcases/tcEdit.php— the guard -
CHANGELOG— one-line summary -
docs/Bugfix-Issue-1859-tcEdit-NoActiveVersion-500.md— docs mirror -
tmp/TLU_Test_Cases.md— suite "Regression — Issue #1859" (7/7 PASS) -
tmp/fixtures_1859.php,tmp/verify_1859.sh,tmp/repro_1859_req.php— repro + regression harness
Commits on fix/issue-1859: d1dfc415b (fix), de9876bf1 (regression suite), 6eec9f814 (docs & CHANGELOG), and the code-review-findings commit.