phacility/phabricator · error · Exception

CircleCI did not return a "%s"!

Error message

CircleCI did not return a "%s"!

What it means

The POST to circleci.com/api/v1/project/... returned a non-error HTTP status and the body parsed as JSON, but the decoded object has no 'build_url' key. The step needs that URL to create the 'View in CircleCI' URI artifact, so a 2xx response without build_url (typically a JSON error object such as {"message": ...} from CircleCI) fails the build with this exception.

Source

Thrown at src/applications/harbormaster/step/HarbormasterCircleCIBuildStepImplementation.php:207

      ->addHeader('Accept', 'application/json')
      ->setTimeout(60);

    $this->resolveFutures(
      $build,
      $build_target,
      array($future));

    $this->logHTTPResponse($build, $build_target, $future, pht('CircleCI'));

    list($status, $body) = $future->resolve();
    if ($status->isError()) {
      throw new HarbormasterBuildFailureException();
    }

    $response = phutil_json_decode($body);
    $build_uri = idx($response, 'build_url');
    if (!$build_uri) {
      throw new Exception(
        pht(
          'CircleCI did not return a "%s"!',
          'build_url'));
    }

    $target_phid = $build_target->getPHID();

    // Write an artifact to create a link to the external build in CircleCI.

    $api_method = 'harbormaster.createartifact';
    $api_params = array(
      'buildTargetPHID' => $target_phid,
      'artifactType' => HarbormasterURIArtifact::ARTIFACTCONST,
      'artifactKey' => 'circleci.uri',
      'artifactData' => array(
        'uri' => $build_uri,
        'name' => pht('View in CircleCI'),
        'ui.external' => true,

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Open the build target log: logHTTPResponse() recorded the raw HTTP response, which shows exactly what CircleCI returned.
  2. Confirm the project is enabled on CircleCI and the token has access to the namespace/project the step built.
  3. Re-test the exact URL from the log with curl using the same token to reproduce the response outside Phabricator.
  4. If CircleCI's API shape changed, update/patch HarbormasterCircleCIBuildStepImplementation or upgrade Phabricator.
Defensive patterns

Strategy: try-catch

Validate before calling

// Sanity-check reachability before the build (optional, does not guarantee build_url):
list($status) = id(new HTTPSFuture('https://circleci.com/api/v1/me?circle-token='.$token))
  ->resolve();
if ($status->isError()) {
  // token/project problem - fix before running builds
}

Try / catch

try {
  // run the CircleCI step
} catch (Exception $ex) {
  if (preg_match('/did not return a "build_url"/', $ex->getMessage())) {
    // inspect the logged HTTP response body for the actual CircleCI payload;
    // fix project/token config, then re-run the build
  }
}

Prevention

When it happens

Trigger: CircleCI answers 200 with an error payload: project not enabled on CircleCI, token lacking scope for the project, or an API-shape change (the v1 API being deprecated/changed). Also possible with intermediaries (proxies) that return their own JSON on 2xx.

Common situations: The CircleCI project was never enabled ('Follow' the project on CircleCI); the token belongs to a different user/org; CircleCI v1 API behavior changed after maintenance; builds worked before a CircleCI or Phabricator upgrade.

Related errors


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