Skip to content

Bugfix Issue 1577 Codetracker Invalid Type Warnings

github-actions[bot] edited this page Sep 25, 2026 · 1 revision

Bug fix — Issue #1577: unregistered Code Tracker types were persisted and generated Event Viewer warnings

Symptom

The modern Code Tracker BFF accepted arbitrary integer values in the type field. A crafted create request with type: 6 returned HTTP 200, persisted the unknown type, and the following list/delete requests dereferenced missing system metadata. PHP 8.3 recorded ten E_WARNING rows in Event Viewer from tlCodeTracker.class.php:116,120,124,559,560.

Entry points:

  • API: http://localhost:8082/api/codetracker/index.php
  • Screen: http://localhost:8082/gui/templates/codetracker/codetrackerView.html

Reproduction before the fix

  1. Authenticate as admin with codetracker_management right 51.
  2. POST {"name":"repro-1577-unknown","type":6,"cfg":""} to the API root.
  3. Request the collection and the returned tracker detail.
  4. Delete the temporary tracker and inspect Event Viewer.

Measured result: create, list, and delete all returned HTTP 200. Type 6 was persisted even though the registered enabled systems were only type 1 (stash) and type 200 (github). Event Viewer contained ten new warnings generated by the legacy lookups; the browser showed no JavaScript exception.

Root cause chain

  1. The BFF create route previously applied intval() to any submitted type but never checked it against tlCodeTracker::getSystems().
  2. The update route had the same lossy coercion and also did not distinguish an omitted partial-update type from an explicitly supplied value.
  3. tlCodeTracker::create() and update() persisted the unchecked integer.
  4. Serialization and delete handling then indexed $systems[$type] and $implementations[$type] without a presence guard. Missing metadata produced the warnings instead of a client error.
  5. The structured 400 response had no UI mapping, so adding BFF validation also required a localized client message.

Why it breaks now: the REST create/update surface was added during the Code Tracker modernization without the validation that the normal type selector makes implicit in the browser. Direct API clients could bypass that UI constraint.

Blast radius: authenticated managers could create an unusable row or change a valid row to an unusable type. Anonymous and view-only requests remained protected by the existing 401/403 gates; those checks execute before the new type validation.

Fix approach

The BFF is the trust boundary, so validation was added there rather than relying on the browser type selector.

  • api/codetracker/index.php:82 requires request bodies to be top-level JSON objects. Scalar, list, and malformed bodies return HTTP 400 {"status":"error","code":"invalid_body"} instead of reaching array access or producing a PHP error.
  • api/codetracker/index.php:91 accepts only JSON integers or canonical signed decimal strings. Booleans, floats, null, objects, arrays, and strings with trailing characters are rejected before lossy coercion.
  • api/codetracker/index.php:102 checks the normalized value against getSystems(['status' => 'enabled']). Unknown and disabled systems return HTTP 400 with code=invalid_type and the rejected integer.
  • api/codetracker/index.php:200 validates create input before persistence.
  • api/codetracker/index.php:233 validates an explicitly supplied update type before loading or changing the tracker. An omitted type remains a valid partial update and retains the stored type.
  • gui/templates/codetracker/codetrackerView.html:397 maps invalid_type to ct.msg.invalidType; the key exists in all 10 modern locale bundles.

Authorization ordering is unchanged: same-origin, authentication, page read rights, and management rights all run before body/type validation.

Alternatives considered and rejected

  • Harden only tlCodeTracker::getByID()/serialization: this would suppress warnings but still persist an invalid type and leave list/delete behavior ambiguous. The BFF must reject invalid state at ingress.
  • Accept any registered type, including disabled systems: disabled systems are not usable and should not be creatable through the API. Validation uses the enabled-system set.
  • Coerce with intval() before validation: values such as true, 1.5, or 1junk can alias a registered integer. Raw values are normalized strictly first.
  • Treat omitted PUT type as zero and reject it: that would break the existing rename/config-only partial update. Presence is checked separately.
  • Return a hardcoded English PHP error: violates the BFF i18n contract and would expose implementation wording in the modern screen.

Verification

  • php -l api/codetracker/index.php and git diff --check: clean.
  • Inline JavaScript parses successfully; all 10 locale bundles pass python3 -m json.tool.
  • Registered types 1 and 200 retain create, list, detail, update, and delete behavior. Type transitions 1→200 and 200→1 pass.
  • Unknown, disabled, malformed, boolean, float, null, and trailing-text type values return HTTP 400 without persistence.
  • Omitted PUT type retains the stored type.
  • Anonymous invalid create returns 401; a temporary user holding only codetracker_view receives 403 on create and stored-token connection paths.
  • The create modal displays Code Tracker type 999 is unknown. and remains open; the collection remains empty.
  • Event Viewer WARNING/ERROR count remains exactly 10, all created by the pre-fix reproduction. Rows with id > 11 at levels 2/4: 0.
  • Regression suite in tmp/TLU_Test_Cases.md: 8/8 PASS.

Screenshots

Before the fix, Event Viewer shows the ten PHP warnings produced by create, list, and delete operations against the unknown tracker type:

Issue 1577 before fix — Event Viewer warnings

After the fix, the create modal keeps the user's input and displays the localized structured error; the unknown tracker is not added to the table:

Issue 1577 after fix — localized invalid type error

Files changed

  • api/codetracker/index.php — request-shape and enabled tracker-type guards.
  • gui/templates/codetracker/codetrackerView.html — structured error rendering.
  • gui/templates/i18n/{de,en,es,fr,it,ja,pt,ro,ru,zh}.json — localized message.
  • tmp/TLU_Test_Cases.md — Issue #1577 regression suite.
  • CHANGELOG and this Wiki/docs mirror.

Result

Issue #1577 is fixed on fix/issue-1577 in commits 4497f11bb (fix) and f25761c01 (regression suite). The original warning-producing path is rejected before persistence, normal registered-type behavior is preserved, and no new Event Viewer warning was generated.

Clone this wiki locally