phacility/phabricator · error · Exception
Changeset ID "%s" is part of diff ID "%s", but that diff is
Error message
Changeset ID "%s" is part of diff ID "%s", but that diff is attached to revision "%s", not revision "%s".
What it means
Even when the revision and the changeset both exist, the controller verifies they belong together: the changeset's diff must be attached to the same revision. A mismatch throws this error. The check protects against stale parameter mixing and cross-revision request construction.
Source
Thrown at src/applications/differential/controller/DifferentialInlineCommentEditController.php:54
$changeset_id = $this->getChangesetID();
$viewer = $this->getViewer();
$revision = $this->loadRevision();
$changeset = id(new DifferentialChangesetQuery())
->setViewer($viewer)
->withIDs(array($changeset_id))
->executeOne();
if (!$changeset) {
throw new Exception(
pht(
'Invalid changeset ID "%s"!',
$changeset_id));
}
$diff = $changeset->getDiff();
if ($diff->getRevisionID() != $revision->getID()) {
throw new Exception(
pht(
'Changeset ID "%s" is part of diff ID "%s", but that diff '.
'is attached to revision "%s", not revision "%s".',
$changeset_id,
$diff->getID(),
$diff->getRevisionID(),
$revision->getID()));
}
return id(new DifferentialInlineComment())
->setRevision($revision)
->setChangesetID($changeset_id);
}
protected function loadCommentForDone($id) {
$viewer = $this->getViewer();
$inline = $this->loadCommentByID($id);View on GitHub (pinned to 5720a38cfe)
Solutions
- Always derive both the revision id and the changeset id from the same revision/diff view.
- Re-render the comment form after the revision updates, so it embeds current IDs.
- In automation, fetch the changesets of the specific revision and use only those IDs.
Defensive patterns
Strategy: validation
Validate before calling
// before posting an inline comment, confirm the changeset id belongs to the
// revision being commented on
$changeset_ids = array(); // ids rendered with the current diff view
if (!in_array($changeset_id, $changeset_ids, true)) {
throw new InvalidArgumentException(
'Changeset does not belong to this revision.');
} Try / catch
try {
// submit the inline comment
} catch (Exception $ex) {
if (preg_match('/is part of diff ID/', $ex->getMessage())) {
// mixed ids: refresh both from the same revision view and resubmit
} else {
throw $ex;
}
} Prevention
- Derive the revision id and the changeset id from the same diff view.
- Re-render comment forms after revision updates so embedded ids stay current.
- Do not reuse captured changeset ids across revisions.
When it happens
Trigger: Mixing a changeset id from revision A with the revision id of revision B in one inline-comment request — stale forms, request replay, or hand-built parameters.
Common situations: Two revisions open in parallel with a copy-pasted URL; automation that caches changeset IDs and reuses them across revisions.
Related errors
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/cc821a1a76032bf0.
Report an issue: GitHub.