phacility/phabricator · error · PhabricatorEditorURIParserException

Editor pattern "%s" is invalid: the pattern must begin with

Error message

Editor pattern "%s" is invalid: the pattern must begin with a valid editor protocol, but does not begin with a recognized protocol string.

What it means

The engine takes the first literal token of the editor pattern and feeds it to PhutilURI->getProtocol(). If PhutilURI cannot recognize any 'scheme:' prefix in that literal (empty protocol string), the pattern is rejected because every valid editor link must be driven by a concrete protocol handler. This catches patterns that begin with a bare word, path, or macro text instead of 'something://'.

Source

Thrown at src/infrastructure/editor/PhabricatorEditorURIEngine.php:214

        }
        break;
      }

      if ($first_literal === null) {
        throw new PhabricatorEditorURIParserException(
          pht(
            'Editor pattern "%s" is invalid: the pattern must begin with '.
            'a valid editor protocol, but begins with a variable. This is '.
            'very sneaky and also very forbidden.',
            $raw_pattern));
      }
    }

    $uri = new PhutilURI($first_literal);
    $editor_protocol = $uri->getProtocol();

    if (!$editor_protocol) {
      throw new PhabricatorEditorURIParserException(
        pht(
          'Editor pattern "%s" is invalid: the pattern must begin with '.
          'a valid editor protocol, but does not begin with a recognized '.
          'protocol string.',
          $raw_pattern));
    }

    $allowed_key = 'uri.allowed-editor-protocols';
    $allowed_protocols = PhabricatorEnv::getEnvConfig($allowed_key);
    if (empty($allowed_protocols[$editor_protocol])) {
      throw new PhabricatorEditorURIParserException(
        pht(
          'Editor pattern "%s" is invalid: the pattern must begin with '.
          'a valid editor protocol, but the protocol "%s://" is not allowed.',
          $raw_pattern,
          $editor_protocol));
    }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Convert the command into a custom protocol URI registered by your editor (e.g. 'mvim://open?url=file://%f&line=%l') and set that as the pattern.
  2. Verify the leading literal really contains 'scheme://' before the first variable; fix via `./bin/config set editor ...` or the user preference.
  3. If you need a custom scheme, make sure your OS/browser has a handler for it - Phabricator only needs the scheme in the pattern string itself.

Example fix

// before: shell command, not a URI
vim %f +%l

// after: protocol-based pattern
vim://open?url=file://%f&line=%l
Defensive patterns

Strategy: validation

Validate before calling

$tokens = PhabricatorEditorURIEngine::newPatternTokens($pattern);
$literal = null;
if ($tokens) {
  if ($tokens[0]['type'] === 'literal') {
    $literal = $tokens[0]['value'];
  }
}
if ($literal === null || !(new PhutilURI($literal))->getProtocol()) {
  // reject before save: first literal carries no 'scheme://'
  throw new Exception('Editor pattern must start with scheme://');
}

Try / catch

try {
  $engine->newURITokensForRepository(); // triggers full parse chain
} catch (PhabricatorEditorURIParserException $ex) {
  $dialog = $this->newDialog()->setTitle(pht('Invalid Editor Pattern'));
  // render $ex->getMessage() to the user and keep the old pattern active
}

Prevention

When it happens

Trigger: A pattern like 'open-in-editor %%f' or 'gnome-open %f' whose leading literal contains no 'proto://' - PhutilURI parses no protocol, $editor_protocol is empty, and the exception fires right after the first-literal check.

Common situations: Entering a shell command instead of a URI in the editor-link preference (expecting Phabricator to exec it); old-style patterns from pre-URI editor integrations; a literal prefix that is just whitespace or punctuation.

Related errors


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