phacility/phabricator · error · PhabricatorTypeaheadInvalidTokenException

Unable to parse function and arguments for token "%s".

Error message

Unable to parse function and arguments for token "%s".

What it means

Typeahead datasources tokenize function expressions like 'viewer()' or 'user(alice)'. parseFunction() in strict mode (allow_partial=false) requires a fully-formed 'name(args)' string with balanced parentheses; anything else throws PhabricatorTypeaheadInvalidTokenException with this message.

Source

Thrown at src/applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php:488

    return ($token !== null && strpos($token, '(') !== false);
  }


  /**
   * @task functions
   */
  protected function parseFunction($token, $allow_partial = false) {
    $matches = null;

    if ($allow_partial) {
      $ok = preg_match('/^([^(]+)\((.*?)\)?\z/', $token, $matches);
    } else {
      $ok = preg_match('/^([^(]+)\((.*)\)\z/', $token, $matches);
    }

    if (!$ok) {
      if (!$allow_partial) {
        throw new PhabricatorTypeaheadInvalidTokenException(
          pht(
            'Unable to parse function and arguments for token "%s".',
            $token));
      }
      return null;
    }

    $function = trim($matches[1]);

    if (!$this->canEvaluateFunction($function)) {
      if (!$allow_partial) {
        throw new PhabricatorTypeaheadInvalidTokenException(
          pht(
            'This datasource ("%s") can not evaluate the function "%s(...)".',
            get_class($this),
            $function));
      }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Send well-formed function tokens: name plus balanced parentheses, e.g. 'viewer()' or 'user(alice)'.
  2. For plain values, submit the raw string without parentheses so it is treated as a literal token.
  3. Catch PhabricatorTypeaheadInvalidTokenException and drop or re-prompt for the offending token instead of failing the whole query.
  4. Validate tokens with the same regex ('/^([^(]+)\((.*)\)\z/') before storing or forwarding them.

Example fix

// before
$token = 'viewer(';

// after
$token = 'viewer()';
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-validate function tokens before storing/forwarding them
if (preg_match('/\(.*\)/', $token)) { // looks like a function
  if (!preg_match('/^([^(]+)\((.*)\)\z/', $token)) {
    // reject or repair the token before it reaches the datasource
    $token = null;
  }
}

Type guard

function isWellFormedFunctionToken($token) {
  return is_string($token)
    && preg_match('/^([^(]+)\((.*)\)\z/s', $token) === 1;
}

Try / catch

try {
  $function = $datasource->parseFunction($token);
} catch (PhabricatorTypeaheadInvalidTokenException $ex) {
  // drop the malformed token and continue with the rest of the query
}

Prevention

When it happens

Trigger: Passing a malformed function token to a datasource's tokenize/evaluate path: 'viewer(' (missing close paren), 'func)(', empty name '()', or stray text after the closing parenthesis; typically from stored queries, bookmarked tokens, or Conduit callers submitting raw tokenizer values.

Common situations: Hand-crafted Conduit search constraints with function tokens; URL parameters copied from a form and truncated; tokens built by string concatenation that drops the '()' suffix; older saved queries surviving a format change.

Understand the failure class

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/13c22098beec0338. Report an issue: GitHub.