phacility/phabricator · error · Exception

Can not create an image with nonpositive dimensions.

Error message

Can not create an image with nonpositive dimensions.

What it means

PhabricatorFileImageTransform::newEmptyImage($w, $h) casts both arguments to int and refuses to allocate a GD canvas when either is <= 0. A nonpositive dimension means the transform computed a degenerate output size (typically scaling a tiny image down so far that a side rounds to zero), and GD cannot create a 0-pixel image, so this fails fast with a clear message instead of a raw GD error.

Source

Thrown at src/applications/files/transform/PhabricatorFileImageTransform.php:167

    $properties = $this->getFileProperties() + $defaults;

    return PhabricatorFile::newFromFileData($data, $properties);
  }


  /**
   * Create a new image filled with transparent pixels.
   *
   * @param int Desired image width.
   * @param int Desired image height.
   * @return resource New image resource.
   */
  protected function newEmptyImage($w, $h) {
    $w = (int)$w;
    $h = (int)$h;

    if (($w <= 0) || ($h <= 0)) {
      throw new Exception(
        pht('Can not create an image with nonpositive dimensions.'));
    }

    $trap = new PhutilErrorTrap();
    $img = @imagecreatetruecolor($w, $h);
    $errors = $trap->getErrorsAsString();
    $trap->destroy();
    if ($img === false) {
      throw new Exception(
        pht(
          'Unable to imagecreatetruecolor() a new empty image: %s',
          $errors));
    }

    $trap = new PhutilErrorTrap();
    $ok = @imagesavealpha($img, true);
    $errors = $trap->getErrorsAsString();
    $trap->destroy();

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Clamp computed dimensions to at least 1 before creating the canvas: $w = max(1, (int)$w); $h = max(1, (int)$h);
  2. In custom transforms, reject or skip images whose source dimensions are smaller than the target scale factor rather than producing a 0-sized output.
  3. Validate transform configuration so width/height/percent parameters cannot be zero or negative.

Example fix

// before
$dst = $this->newEmptyImage($s * $this->w, $s * $this->h); // can be < 1

// after
$w = max(1, (int)round($s * $this->w));
$h = max(1, (int)round($s * $this->h));
$dst = $this->newEmptyImage($w, $h);
Defensive patterns

Strategy: validation

Validate before calling

$w = max(1, (int)round($w));
$h = max(1, (int)round($h));
// now safe to call newEmptyImage($w, $h)

Type guard

function isPositiveDimensions($w, $h): bool {
  return ((int)$w > 0) && ((int)$h > 0);
}

Prevention

When it happens

Trigger: A transform whose computed destination width or height is 0 or negative — e.g. scaling a 1px-wide image to 1% scale, or a custom subclass passing user-controlled dimensions into newEmptyImage(); also any code path that passes null (casts to 0) or a negative offset.

Common situations: Custom PhabricatorFileImageTransform subclasses with arithmetic like floor($w * $scale) that yields 0 for small inputs; transforms configured with a dimension of 0 in config; division by a large scaling factor producing values < 1 that truncate to 0.

Related errors


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