{"record":{"id":"25582438d8ee9253","repo":"phacility/phabricator","slug":"failed-to-parse-line-s","errorCode":null,"errorMessage":"Failed to parse line '%s'.","messagePattern":"Failed to parse line '(.+?)'\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/repository/worker/commitchangeparser/PhabricatorRepositoryGitCommitChangeParserWorker.php","lineNumber":110,"sourceCode":"          $change_target = $src_path;\n          $move_away[$change_target][] = $change_path;\n          break;\n        case 'T':\n          // Type of the file changed, fall through and treat it as a\n          // modification. Not 100% sure this is the right thing to do but it\n          // seems reasonable.\n        case 'M':\n          if ($file_type == DifferentialChangeType::FILE_DIRECTORY) {\n            $change_type = DifferentialChangeType::TYPE_CHILD;\n            $is_direct = false;\n          } else {\n            $change_type = DifferentialChangeType::TYPE_CHANGE;\n          }\n          break;\n        // NOTE: \"U\" (unmerged) and \"X\" (unknown) statuses are also possible\n        // in theory but shouldn't appear here.\n        default:\n          throw new Exception(pht(\"Failed to parse line '%s'.\", $line));\n      }\n\n      $changes[$change_path] = array(\n        'repositoryID'      => $repository->getID(),\n        'commitID'          => $commit->getID(),\n\n        'path'              => $change_path,\n        'changeType'        => $change_type,\n        'fileType'          => $file_type,\n        'isDirect'          => $is_direct,\n        'commitSequence'    => $commit->getEpoch(),\n\n        'targetPath'        => $change_target,\n        'targetCommitID'    => $change_target ? $commit->getID() : null,\n      );\n    }\n\n    // Add a change to '/' since git doesn't mention it.","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/repository/worker/commitchangeparser/PhabricatorRepositoryGitCommitChangeParserWorker.php#L92-L128","documentation":"PhabricatorRepositoryGitCommitChangeParserWorker parses git diff-tree --raw output line by line, mapping each status letter (A/D/M/T, etc.) to a DifferentialChangeType; any status or malformed line that falls through the switch throws (PhabricatorRepositoryGitCommitChangeParserWorker.php:110). Renames/copies with detection unexpectedly enabled, unknown status letters, or garbage injected into git's stdout break the parse.","triggerScenarios":"git emitting a change-status letter the switch does not handle; a git wrapper (GIT_EXTERNAL_DIFF, core.pager, aliases) or error message injecting non-diff lines into stdout; corrupted objects producing malformed raw output.","commonSituations":"Newer git versions changing raw diff formats; wrappers or locale settings on the daemon host; shallow/partial clones emitting warnings on stdout during diff-tree.","solutions":["Manually run the parser's command in the repository to see the offending line: git diff-tree --no-commit-id -r --raw <sha>","Remove any git wrappers/hooks/aliases that write to stdout, and ensure the daemon runs a clean git environment","Update Phabricator (parser fixes for new git output land upstream) or pin git to a compatible version, then reparse the commit"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Sanity-check git output shape before parsing (pre-flight in dev):\n//   git diff-tree --no-commit-id -r --raw <sha>\n// Confirm every line's status column is one of A/D/M/T before relying on the parser.","typeGuard":null,"tryCatchPattern":"try {\n  $changes = $parser->parseChanges($repository, $commit);\n} catch (Exception $ex) {\n  // Preserve $line from the message to identify the raw output anomaly,\n  // then inspect the repo manually; do not blind-retry.\n  phlog($ex);\n  throw new PhabricatorWorkerPermanentFailureException($ex->getMessage());\n}","preventionTips":["Run a clean, wrapper-free git environment on daemon hosts (no GIT_EXTERNAL_DIFF, aliases, or wrappers writing to stdout)","Pin git versions on Phabricator hosts and test parser compatibility before upgrades","Test imports of unusual commits (submodules, mode changes, merges) in a staging copy first"],"tags":["phabricator","git","parsing","diff-tree","vcs-adapter","php"],"backgroundTag":"vcs-output-parse-failure","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}