phacility/phabricator · error · Exception

Field "slug" must be non-empty.

Error message

Field "slug" must be non-empty.

What it means

The phriction.create Conduit method requires the slug field (the wiki document path); execute() rejects a null or zero-length slug before any query runs. It is thrown as a plain Exception rather than a ConduitException, so Conduit clients see a generic error instead of a structured error code.

Source

Thrown at src/applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php:29

  }

  protected function defineParamTypes() {
    return array(
      'slug'          => 'required string',
      'title'         => 'required string',
      'content'       => 'required string',
      'description'   => 'optional string',
    );
  }

  protected function defineReturnType() {
    return 'nonempty dict';
  }

  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)))
      ->requireCapabilities(
        array(
          PhabricatorPolicyCapability::CAN_VIEW,
          PhabricatorPolicyCapability::CAN_EDIT,
        ))
      ->executeOne();
    if ($doc) {
      throw new Exception(pht('Document already exists!'));
    }

    $doc = PhrictionDocument::initializeNewDocument(
      $request->getUser(),
      $slug);

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Pass a non-empty slug in the conduit call parameters
  2. Build the slug defensively and give it a fallback value before calling phriction.create
  3. Normalize client-side with the same rules PhabricatorSlug::normalize() applies so the stored path matches expectations

Example fix

// before: slug built from a possibly-empty variable
$client->callMethodSynchronous('phriction.create', array(
  'slug' => $computed_slug,
  'title' => $title,
  'content' => $content,
));

// after: guarantee a non-empty slug before the call
if ($computed_slug === null || !strlen($computed_slug)) {
  $computed_slug = PhabricatorSlug::normalize($title);
}
$client->callMethodSynchronous('phriction.create', array(
  'slug' => $computed_slug,
  'title' => $title,
  'content' => $content,
));
Defensive patterns

Strategy: validation

Validate before calling

$slug = (string)idx($params, 'slug', '');
if ($slug === '') {
  throw new InvalidArgumentException('phriction.create: slug must be non-empty');
}
$result = $client->callMethodSynchronous('phriction.create', $params);

Try / catch

try {
  $result = $client->callMethodSynchronous('phriction.create', $params);
} catch (Exception $ex) {
  if (strpos($ex->getMessage(), 'must be non-empty') !== false) {
    // report as a caller parameter bug, not a server problem
  }
}

Prevention

When it happens

Trigger: Calling conduit method phriction.create with slug set to an empty string (presence checks pass, the strlen guard does not) or with slug explicitly null via a loose client.

Common situations: Client code builds the slug from a variable that is sometimes empty: an unset title, a blank form field, or slugification that produced nothing from punctuation-only or unicode input.

Related errors


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