phacility/phabricator · error · Exception
This transcript has an invalid or inaccessible adapter.
Error message
This transcript has an invalid or inaccessible adapter.
What it means
Thrown by HeraldTranscriptController when rendering a stored Herald transcript whose object type has no enabled adapter for the current viewer. The controller builds the adapter map with HeraldAdapter::getEnabledAdapterMap($viewer); if the transcript's type key is absent (adapter's application uninstalled/disabled, adapter removed from the install, or policy filtering hides it), access is blocked deliberately — the source TODO notes this guard exists so transcript details never leak past application policies.
Source
Thrown at src/applications/herald/controller/HeraldTranscriptController.php:60
if (!$object_xscript) {
$notice = id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
->setTitle(pht('Old Transcript'))
->appendChild(phutil_tag(
'p',
array(),
pht('Details of this transcript have been garbage collected.')));
$content[] = $notice;
} else {
$map = HeraldAdapter::getEnabledAdapterMap($viewer);
$object_type = $object_xscript->getType();
if (empty($map[$object_type])) {
// TODO: We should filter these out in the Query, but we have to load
// the objectTranscript right now, which is potentially enormous. We
// should denormalize the object type, or move the data into a separate
// table, and then filter this earlier (and thus raise a better error).
// For now, just block access so we don't violate policies.
throw new Exception(
pht('This transcript has an invalid or inaccessible adapter.'));
}
$this->adapter = HeraldAdapter::getAdapterForContentType($object_type);
$phids = $this->getTranscriptPHIDs($xscript);
$phids = array_unique($phids);
$phids = array_filter($phids);
$handles = $this->loadViewerHandles($phids);
$this->handles = $handles;
$warning_panel = $this->buildWarningPanel($xscript);
$content[] = $warning_panel;
$content[] = $this->newContentView($xscript, $view_key);
}
View on GitHub (pinned to 5720a38cfe)
Solutions
- Re-enable or install the application that owns the transcript's content type (Applications → search the relevant app → Install/Enable), then reload the transcript.
- If the adapter is gone permanently (removed upstream or custom), treat the transcript as unviewable and garbage-collect old transcripts (Herald transcript GC) rather than hacking around the guard.
- For custom adapters, keep the content-type key stable across renames so old transcripts keep resolving.
- Verify the viewing user's policy actually permits the adapter's application — the map is viewer-filtered.
Defensive patterns
Strategy: validation
Validate before calling
// Before rendering a transcript, confirm its type is still enabled
$map = HeraldAdapter::getEnabledAdapterMap($viewer);
if (!isset($map[$transcript->getType()])) {
// render a 'transcript unavailable' notice instead of throwing;
// optionally filter these transcripts out of list queries up front
} Type guard
function transcriptAdapterIsEnabled($viewer, $type) {
return isset(HeraldAdapter::getEnabledAdapterMap($viewer)[$type]);
} Try / catch
try {
// transcript render path
} catch (Exception $ex) {
if (strpos($ex->getMessage(), 'invalid or inaccessible adapter') !== false) {
// show 'details unavailable (application disabled)' page; do not
// leak policy-relevant transcript data by working around the guard
}
} Prevention
- Keep application content-type keys stable when writing custom adapters so old transcripts keep resolving.
- Before uninstalling an application, expect its Herald transcripts to become unviewable — purge them via GC first if you need the history gone cleanly.
- Denormalize the object type on transcripts (per the source TODO) so list queries can filter these out earlier.
When it happens
Trigger: Opening /herald/transcript/<id>/ after the application that produced the transcript (e.g. Differential, Diffusion, Paste) was uninstalled or disabled in Applications config; loading an old transcript from a since-removed custom adapter; a viewer whose policy filtering removes the adapter from the enabled map.
Common situations: Admins uninstall an unused application, then click an old Herald transcript link from a notification or search. Transcripts produced by custom/extension adapters after the extension was disabled or renamed. Upgrades that drop or rename an adapter's content-type key.
Related errors
- No valid object provided for object rule!
- Object is of wrong type for adapter!
- The regular expression "%s" is not valid. Regular expression
- The regular expression pair "%s" is not valid JSON. Enter a
- The regular expression pair "%s" must have exactly two eleme
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/5468811b0acaad1e.
Report an issue: GitHub.