phacility/phabricator · error · Exception

Failed to parse line

Error message

Failed to parse line '%s'.

What it means

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.

Solutions

  1. Manually run the parser's command in the repository to see the offending line: git diff-tree --no-commit-id -r --raw <sha>
  2. Remove any git wrappers/hooks/aliases that write to stdout, and ensure the daemon runs a clean git environment
  3. Update Phabricator (parser fixes for new git output land upstream) or pin git to a compatible version, then reparse the commit
Defensive patterns

Strategy: try-catch

Validate before calling

// Sanity-check git output shape before parsing (pre-flight in dev):
//   git diff-tree --no-commit-id -r --raw <sha>
// Confirm every line's status column is one of A/D/M/T before relying on the parser.

Try / catch

try {
  $changes = $parser->parseChanges($repository, $commit);
} catch (Exception $ex) {
  // Preserve $line from the message to identify the raw output anomaly,
  // then inspect the repo manually; do not blind-retry.
  phlog($ex);
  throw new PhabricatorWorkerPermanentFailureException($ex->getMessage());
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


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

Appendix: source

Thrown at src/applications/repository/worker/commitchangeparser/PhabricatorRepositoryGitCommitChangeParserWorker.php:110

          $change_target = $src_path;
          $move_away[$change_target][] = $change_path;
          break;
        case 'T':
          // Type of the file changed, fall through and treat it as a
          // modification. Not 100% sure this is the right thing to do but it
          // seems reasonable.
        case 'M':
          if ($file_type == DifferentialChangeType::FILE_DIRECTORY) {
            $change_type = DifferentialChangeType::TYPE_CHILD;
            $is_direct = false;
          } else {
            $change_type = DifferentialChangeType::TYPE_CHANGE;
          }
          break;
        // NOTE: "U" (unmerged) and "X" (unknown) statuses are also possible
        // in theory but shouldn't appear here.
        default:
          throw new Exception(pht("Failed to parse line '%s'.", $line));
      }

      $changes[$change_path] = array(
        'repositoryID'      => $repository->getID(),
        'commitID'          => $commit->getID(),

        'path'              => $change_path,
        'changeType'        => $change_type,
        'fileType'          => $file_type,
        'isDirect'          => $is_direct,
        'commitSequence'    => $commit->getEpoch(),

        'targetPath'        => $change_target,
        'targetCommitID'    => $change_target ? $commit->getID() : null,
      );
    }

    // Add a change to '/' since git doesn't mention it.

View on GitHub (pinned to 5720a38cfe)