phacility/phabricator · error · Exception

Failed to parse line '%s'.

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.

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)

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.