phacility/phabricator · error · ConduitException

ERR-BAD-DOCUMENT

ERR-BAD-DOCUMENT

Error message

No such document exists.

What it means

phriction.history looks up the document by normalized slug; on miss it raises a ConduitException with error code ERR-BAD-DOCUMENT, which the method declares in defineErrorTypes(). Well-behaved Conduit clients therefore get a structured, catchable error code instead of having to string-match.

Solutions

  1. Verify the slug with phriction.info (same code path) or in the web UI
  2. Check the acting user's view access to the document
  3. Catch ERR-BAD-DOCUMENT client-side and degrade gracefully (skip, log, or prompt)
Defensive patterns

Strategy: try-catch

Try / catch

try {
  $result = $client->callMethodSynchronous('phriction.history', $params);
} catch (ConduitClientException $ex) {
  if ($ex->getErrorCode() === 'ERR-BAD-DOCUMENT') {
    // slug unknown to this viewer: skip, log, or prompt for the correct path
  }
}

Prevention

When it happens

Trigger: Calling phriction.history with a slug that does not exist or that the acting user cannot see, so the policy-filtered PhrictionDocumentQuery returns no result.

Common situations: Slug typos or renamed pages; bots whose view policy excludes them from the document; querying documents that were deleted.

Related errors


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

Appendix: source

Thrown at src/applications/phriction/conduit/PhrictionHistoryConduitAPIMethod.php:50

  protected function defineErrorTypes() {
    return array(
      'ERR-BAD-DOCUMENT' => pht('No such document exists.'),
    );
  }

  protected function execute(ConduitAPIRequest $request) {
    $slug = $request->getValue('slug');
    if ($slug === null || !strlen($slug)) {
      throw new Exception(pht('Field "slug" must be non-empty.'));
    }

    $doc = id(new PhrictionDocumentQuery())
      ->setViewer($request->getUser())
      ->withSlugs(array(PhabricatorSlug::normalize($slug)))
      ->executeOne();
    if (!$doc) {
      throw new ConduitException('ERR-BAD-DOCUMENT');
    }

    $content = id(new PhrictionContent())->loadAllWhere(
      'documentID = %d ORDER BY version DESC',
      $doc->getID());

    $results = array();
    foreach ($content as $version) {
      $results[] = $this->buildDocumentContentDictionary(
        $doc,
        $version);
    }

    return $results;
  }

}

View on GitHub (pinned to 5720a38cfe)