Skip to content

fwconsole reload crashes with 'Undefined array key trunk_name' — PJSIP trunks never written to config due to broken SQL JOIN in getAllTrunks() #180

@vitvomacko

Description

@vitvomacko

Description

After adding a PJSIP trunk in FreePBX, running fwconsole reload fails with a fatal PHP error (Undefined array key "trunk_name"), and no PJSIP trunks are ever written to Asterisk configuration files. This means all PJSIP trunks are silently broken after every reload.

The bug has two independent root causes in functions.inc/drivers/PJSip.class.php, both in the getAllTrunks() function:

  1. The SQL JOIN condition compares the wrong columns — pjsip.id (a varchar like OUT_sip_maitrea) is compared against trunks.trunkid (an integer primary key). These values never match, so the JOIN returns no rows and trunks are never loaded.
  2. The SQL SELECT only fetches id, keyword, data, but the code later accesses $trunk['trunk_name'] which is never present in the result set, causing a PHP error on every reload whenever a PJSIP trunk exists.

Steps to Reproduce

  1. Install FreePBX 17 on Debian 12 with Asterisk 22.
  2. Create at least one PJSIP trunk via the FreePBX web UI (Connectivity → Trunks → Add Trunk → SIP (PJSIP)).
  3. Run fwconsole reload from the command line.
  4. Observe the PHP error in the output.
  5. Check the generated Asterisk config files — no trunk entries are present.

Expected Behavior

  • fwconsole reload completes without errors.
  • PJSIP trunk configuration is written to the Asterisk config files.
  • Asterisk loads the trunks and calls can be placed/received.

Actual Behavior

fwconsole reload crashes with:

PHP Warning: Undefined array key "trunk_name" in /var/www/html/admin/modules/core/functions.inc/drivers/PJSip.class.php on line 504

PJSIP trunks are never written to any Asterisk configuration file. asterisk -rx "pjsip show endpoints" shows no trunk endpoints.


Environment

Component Version
FreePBX Core module 17.0.18.40
Asterisk 22.7.0
OS Debian 12 (Bookworm)
Database MariaDB (as bundled)

Root Cause Analysis

File: functions.inc/drivers/PJSip.class.php
Function: getAllTrunks() (around line 1607)

Bug 1 — Wrong JOIN column

The current SQL:

SELECT id, keyword, data FROM pjsip as tech
LEFT OUTER JOIN trunks on (tech.id = trunks.trunkid) OR (tech.id = trunks.trunkid)
where trunks.disabled = 'off' OR trunks.disabled IS NULL

pjsip.id stores varchar identifiers like OUT_sip_maitrea, but the JOIN compares against trunks.trunkid which is the integer auto-increment primary key. These never match.

The duplicate OR condition (tech.id = trunks.trunkid) OR (tech.id = trunks.trunkid) is identical in both clauses — strongly suggesting the second clause was meant to reference trunks.channelid instead.

The correct join column is trunks.channelid, which stores the PJSIP string identifier that matches pjsip.id.

Bug 2 — Missing trunk_name in SELECT

The SELECT clause only retrieves id, keyword, data. However at line ~504 the code accesses $trunk['trunk_name'] (which should come from trunks.name), but this column is never selected. PHP 8.x raises Undefined array key and trunk generation fails.


Proposed Fix

SELECT tech.id, tech.keyword, tech.data, trunks.name AS trunk_name
FROM pjsip as tech
INNER JOIN trunks ON tech.id = trunks.channelid
WHERE trunks.disabled = 'off' OR trunks.disabled IS NULL

And in the foreach loop, propagate trunk_name into the result array:

if (!empty($values['trunk_name'])) {
    $final[$values['id']]['trunk_name'] = $values['trunk_name'];
}

Changes and rationale:

  • tech.id = trunks.channelid — correct JOIN column
  • trunks.name AS trunk_name — adds the missing column so line 504 doesn't crash
  • INNER JOIN instead of LEFT OUTER JOIN — prevents orphaned pjsip rows from being returned as incomplete trunk records (the original LEFT JOIN + WHERE trunks.disabled = 'off' was also returning all non-trunk pjsip rows)
  • Explicit tech. prefix on all columns — avoids ambiguity

Tested on FreePBX Core 17.0.18.40 / Asterisk 22.7.0 / Debian 12 Bookworm.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions