{"record":{"id":"d7a3a3924d9fff01","repo":"phacility/phabricator","slug":"editor-pattern-s-is-invalid-the-pattern-contai","errorCode":null,"errorMessage":"Editor pattern \"%s\" is invalid: the pattern contains an unrecognized variable (\"%s\"). Use \"%%%%\" to encode a literal percent symbol.","messagePattern":"Editor pattern \"(.+?)\" is invalid: the pattern contains an unrecognized variable \\(\"(.+?)\"\\)\\. Use \"%%%%\" to encode a literal percent symbol\\.","errorType":"validation","errorClass":"PhabricatorEditorURIParserException","httpStatus":null,"severity":"error","filePath":"src/infrastructure/editor/PhabricatorEditorURIEngine.php","lineNumber":176,"sourceCode":"\n  private function newRawURITokens() {\n    $raw_pattern = $this->getPattern();\n    $raw_tokens = self::newPatternTokens($raw_pattern);\n\n    $variable_definitions = self::getVariableDefinitions();\n\n    foreach ($raw_tokens as $token) {\n      if ($token['type'] !== 'variable') {\n        continue;\n      }\n\n      $value = $token['value'];\n\n      if (isset($variable_definitions[$value])) {\n        continue;\n      }\n\n      throw new PhabricatorEditorURIParserException(\n        pht(\n          'Editor pattern \"%s\" is invalid: the pattern contains an '.\n          'unrecognized variable (\"%s\"). Use \"%%%%\" to encode a literal '.\n          'percent symbol.',\n          $raw_pattern,\n          '%'.$value));\n    }\n\n    $variables = array(\n      '%' => '%',\n    );\n\n    $tokens = $this->newTokensWithVariables($raw_tokens, $variables);\n\n    $first_literal = null;\n    if ($tokens) {\n      foreach ($tokens as $token) {\n        if ($token['type'] === 'literal') {","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/infrastructure/editor/PhabricatorEditorURIEngine.php#L158-L194","documentation":"PhabricatorEditorURIEngine parses the 'editor' URI pattern (from the `editor` config or user preferences) into literal and variable tokens; every %X token must be one of the variables declared in getVariableDefinitions(). The recognized set is %f (file name), %l (line number), %n (repository short name), %d (repository ID), %p (repository PHID), %r (repository callsign) and %% (a literal percent). Any other %-prefixed sequence raises PhabricatorEditorURIParserException at validation time.","triggerScenarios":"Setting `editor` config or a user preference whose pattern contains an unknown placeholder, e.g. 'vim://open?file=%f&line=%L' (capital %L) or 'emacs://%f:%c' (%c is not defined); the pattern is parsed the moment PhabricatorEditorURIEngine::newFromEnvPattern()/newFromUserPattern() tokenizes it.","commonSituations":"Copy-pasting an editor URL template from another tool (VS Code, TextMate, IntelliJ) that uses different placeholders; typos in case (%F vs %f); following outdated documentation that lists variables which no longer or never existed; hand-editing a pattern that was never validated on save.","solutions":["Replace the offending variable with one of the supported ones: %f, %l, %n, %d, %p, %r, or %% for a literal percent sign.","Find the bad pattern with `./bin/config get editor` and re-set it via `./bin/config set editor '...'` (or remove the per-user override in Settings > Preferences > Editor Link).","Test candidate patterns against PhabricatorEditorURIEngine::newPatternTokens() in a scratch script before deploying the config change."],"exampleFix":"// before: %L and %c do not exist\nvim://open?url=file://%f&line=%L&col=%c\n\n// after: only %f and %l are defined\nvim://open?url=file://%f&line=%l","handlingStrategy":"validation","validationCode":"$pattern = 'vim://open?url=file://%f&line=%l';\n$valid = array_keys(PhabricatorEditorURIEngine::getVariableDefinitions());\nforeach (PhabricatorEditorURIEngine::newPatternTokens($pattern) as $token) {\n  if ($token['type'] === 'variable' && !in_array($token['value'], $valid, true)) {\n    throw new Exception('Reject before saving: unknown %'.$token['value']);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  $engine = PhabricatorEditorURIEngine::newFromUserPattern($viewer, $pattern);\n} catch (PhabricatorEditorURIParserException $ex) {\n  $e_pattern = pht('Invalid editor pattern: %s', $ex->getMessage());\n  // return the user to the preferences form with the error attached\n}","preventionTips":["Validate patterns in the settings form via PhabricatorEditorURIEngine::newPatternTokens() on save, not at click time.","Document the supported set (%f, %l, %n, %d, %p, %r, %%) next to the input field.","Set the global default through ./bin/config so only sane patterns ship."],"tags":["phabricator","editor-link","pattern","uri-template","validation"],"backgroundTag":"uri-template-variable-unknown","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}