VoIP.info Guide

Asterisk dialplan lookups and evaluated subroutines

Prove an exact target, understand EVAL_EXTEN target-context evaluation and reserve EVAL_SUB for bounded routines with explicit returns and effects.

Reviewed 2026-10-19Current Asterisk 23 DIALPLAN_EXISTS, EVAL_EXTEN, EVAL_SUB and Return documentation reviewed October 15, 2026; installed branch, loaded modules, generated dialplan, dynamic inputs, target variables, subroutine effects and call outcomes remain deployment specific; no PBX, module set, dialplan, channel, lookup, subroutine, side effect or live call was inspected or testedAdvancedDocumentation based · not lab tested

Separate existence, evaluation and execution

DIALPLAN_EXISTS(), EVAL_EXTEN() and EVAL_SUB() answer different questions. The first checks whether an exact context, extension and priority exists. The second evaluates the application data at a target and returns a string without executing that application. The third runs a Gosub location and returns the value supplied by Return().

Choose the least powerful primitive that meets the requirement. A successful existence check does not prove that normal pattern or include resolution would select that target, that evaluating it is safe, or that a later destination will succeed.

Check the exact target before reading a value

DIALPLAN_EXISTS(context,extension,priority) returns 1 when that exact dialplan target exists and 0 otherwise. Log the bounded context, extension and priority as separate fields and branch on existence before interpreting a returned value.

Keep missing target distinct from a target whose evaluated value is empty. Treat context, extension and priority as control data: map external input to an allow-listed internal name instead of inserting caller-controlled text directly into a dynamic lookup.

Use EVAL_EXTEN for Return data, not application execution

EVAL_EXTEN() looks up a context, extension and priority, evaluates the target application data and returns the result as a string. The target application itself is not executed. In the documented pattern, the target is a Return(...) entry used as a lookup table or function-like value.

Variable and function references are resolved in the target extension context. In particular, ${EXTEN} refers to the extension supplied to EVAL_EXTEN(), not the caller extension. Record both caller and target values when troubleshooting a surprising result.

Reserve EVAL_SUB for logic and arguments

EVAL_EXTEN() cannot pass Gosub arguments. EVAL_SUB() can call a Gosub location with optional arguments and return the value passed to Return(), so it is the appropriate primitive only when real dialplan logic is required. Its documented availability begins in specific maintained branch releases rather than every historical Asterisk version.

Keep the routine short, bounded and independent of channel interaction. The documentation permits arbitrary dialplan, including blocking work, but does not recommend it; a function call hidden inside another expression should not become an unbounded workflow.

Make evaluation-time effects explicit

Function expressions can be evaluated while Asterisk parses application arguments. A routine with writes, network calls, blocking operations or channel mutations can therefore run earlier, more often or in a different branch than an operator expects. Do not call a side-effecting EVAL_SUB() more than once merely to log and then use its result.

Assign the result once, preserve an invocation identifier and branch on the stored value. Keep a side-effect-free control routine for testing. The documented guarantee that EVAL_SUB() returns even if the channel hangs up describes function control flow; it does not prove a live channel, completed side effect or successful call.

Test version, target, return and outcome separately

In an authorized staging context, record the running Asterisk branch, loaded function availability, exact target, DIALPLAN_EXISTS() result, caller and target extension values, arguments, returned string, invocation count and next executed priority. Exercise an existing non-empty return, an existing empty return, a missing target and one bounded EVAL_SUB() routine with no external effects.

Then validate the downstream branch separately and confirm an unrelated control route is unchanged. Remove temporary diagnostics after acceptance. No PBX, module set, dialplan, channel, lookup, subroutine, side effect or live call was tested for this guide.

Keep evaluated dialplan data separate from external database state

The func_odbc guide covers external ODBC query execution, escaping, row cardinality and latency rather than treating it as another dialplan-text lookup.

Keep polled expressions cheap and side-effect free

The WaitForCondition guide treats every function in the condition as repeated work and keeps lookup outcome separate from state ownership.

Confirm which loaded route actually won

The AMI dialplan diagnostic reconstructs context, digits, caller ID, exact matches, patterns, includes and switches before evaluating execution.

Validate a dynamic lookup result once

Use the dialplan input guide to store and validate the returned value before any later dynamic target or branch.

Keep legacy-name migration inside the lookup boundary

The VALID_EXTEN migration guide makes context, extension and priority or label explicit before DIALPLAN_EXISTS() is evaluated.

Sources & applicability

Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.

Examples require adaptation to your topology. No live PBX or hardware testing is claimed.