Freeze the exact expression and first wrong result
Capture one authorized occurrence with timestamp and timezone, Asterisk branch, channel identity, caller context and extension, the complete redacted lookup expression, supplied target context, extension and priority, arguments, returned string, invocation count and next observed priority.
Classify the symptom as a missing target, empty or wrong value, unavailable function, duplicate execution, unexpected side effect, blocking delay or later branch failure. Do not infer a lookup fault only from the final caller outcome.
Prove function and branch availability
Confirm the running branch and loaded function before interpreting behavior. DIALPLAN_EXISTS() predates the evaluated functions, EVAL_EXTEN() has documented introduction points in Asterisk 16, 18 and 19 branches, and EVAL_SUB() begins at documented Asterisk 20, 21 and 22 maintenance releases.
A configuration copied from newer API documentation can therefore fail on an older or differently packaged system. Record the actual branch and module state rather than treating the latest documentation label as the installed version.
Verify the exact target before its return
Evaluate DIALPLAN_EXISTS() with the same bounded context, extension and priority used by the lookup. Compare that tuple with the loaded dialplan, including generated contexts. A 1 proves only that exact target exists; a 0 does not identify which component is wrong.
Keep four cases distinct: target missing, target present with no usable Return data, target returning an empty string and target returning a non-empty string that a later branch rejects.
Reproduce target-context variable resolution
For EVAL_EXTEN(), replace the target temporarily with an authorized, side-effect-free value that exposes redacted caller and target identifiers. Confirm that ${EXTEN} in the evaluated data resolves to the target extension, as documented, and compare other variable or function inputs at that point.
If the lookup was intended to use caller context, pass or copy the required value explicitly rather than assuming evaluation retains the invoking extension. Keep missing variables distinct from present-but-empty values.
Separate EVAL_EXTEN parsing from EVAL_SUB execution
EVAL_EXTEN() parses and evaluates target application data but does not execute the target application or accept Gosub arguments. EVAL_SUB() executes the selected Gosub routine and can pass arguments. Check which contract the design actually needs before changing the target.
If side effects appear, inspect how many times the containing expression is evaluated and whether a function embedded in application arguments ran during parsing. Store one result and reuse it; do not repeat the function for logging, comparison and routing.
Correct one boundary and retest a no-effect control
Correct the demonstrated tuple, install a branch-compatible primitive, use an explicit caller value, add a bounded Return(), pass required EVAL_SUB() arguments or remove external work from the evaluated routine. Change one boundary at a time.
Retest existing, empty and missing targets; target-context variables; one short no-effect subroutine; invocation count; the selected branch; and an unrelated control route. Confirm downstream outcome separately and remove temporary diagnostics. No PBX, module set, dialplan, channel, lookup, subroutine, side effect or live call was tested.
Branch to the external ODBC owner when the lookup crosses the process boundary
For a func_odbc result, use the ODBC-specific diagnostic to inspect connection naming, DSN state, escaping, result cardinality and latency.
A lookup inside a condition can run at every poll
Use the WaitForCondition guide to separate expression cadence, lookup cost, side effects and mutable-state ownership.
Prove the selected priority before blaming a lookup
The AMI dialplan diagnostic first verifies loaded context, match order and the exact executing priority.
Trace the parser when the lookup value is present but changed
The input-parsing diagnostic separates FILTER mutation, REGEX parsing, delimiter count and CUT variable ownership.
Sources & applicability
Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.
- Asterisk 23 DIALPLAN_EXISTS function ↗
- Asterisk 23 EVAL_EXTEN function ↗
- Asterisk 23 EVAL_SUB function ↗
- Asterisk 23 Return application ↗
- Asterisk Configuring res_odbc ↗
- Asterisk func_odbc.conf sample ↗
- Asterisk res_odbc.conf sample ↗
- Asterisk 23 ODBC_FETCH function ↗
- Asterisk 23 SQL_ESC function ↗
- Asterisk 23 SQL_ESC_BACKSLASHES function ↗
- Asterisk security advisory AST-2022-003 ↗
- Asterisk 23 WaitForCondition application ↗
- Asterisk 22 WaitForCondition application ↗
- Asterisk dialplan expressions ↗
- Asterisk conditional applications ↗
- Asterisk 23 VARIABLE_EXISTS function ↗
- Asterisk 23 GLOBAL_EXISTS function ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- ↗
- Asterisk FILTER dialplan function ↗
- Asterisk REGEX dialplan function ↗
- Asterisk ISNULL dialplan function ↗
- Asterisk LEN dialplan function ↗
- Asterisk FIELDQTY dialplan function ↗
- Asterisk CUT dialplan function ↗
- Asterisk dialplan-functions overview ↗
- Asterisk func_strings implementation ↗
Examples require adaptation to your topology. No live PBX or hardware testing is claimed.