Skip to content

fix: warn and fallback for unsupported PHP versions#348

Open
AaronFeledy wants to merge 3 commits into
mainfrom
fix/unsupported-php-version-warning
Open

fix: warn and fallback for unsupported PHP versions#348
AaronFeledy wants to merge 3 commits into
mainfrom
fix/unsupported-php-version-warning

Conversation

@AaronFeledy

@AaronFeledy AaronFeledy commented Mar 23, 2026

Copy link
Copy Markdown
Member

Summary

Fixes #347 — users get a cryptic Docker error when their php_version + php_runtime_generation combination resolves to an image that doesn't exist on Docker Hub:

appserver Error manifest for devwithlando/pantheon-appserver:7.1-5 not found: manifest unknown

Changes

lib/utils.js

  • New PHP_GENERATION_IMAGES map mirrors which images actually exist on Docker Hub (single source of truth)
  • New resolveGeneration() helper picks the requested generation if available, falls back to the highest available generation for that PHP version, or returns null if no images exist
  • getPantheonConfig() validates the (php, generation) combo and emits a user-facing warning when falling back
  • Generalized PHP version normalization handles js-yaml parsing unquoted x.0 as integer x (was hard-coded for 7/8 only)
  • RECOMMENDED_PHP_VERSIONS = ['8.2', '8.3', '8.4'] per Pantheon's PHP support policy

builders/pantheon-php.js

  • Reuses utils.resolveGeneration() as a silent second line of defense, sharing the same source of truth

Combinations now handled

Config Before After
PHP 7.1 (default gen) manifest unknown falls back to 7.1-4
PHP 8.4 + php_runtime_generation: 1 manifest unknown falls back to 8.4-5
PHP 5.3 / 5.5 manifest unknown falls back to x.x-2
php_version: 8.0 (unquoted YAML) spurious warning + silent gen downgrade resolves correctly to 8.0-5
Unknown version (typo, future PHP) manifest unknown strong warning before failure

All 26 (PHP × php_runtime_generation) combinations now resolve to images that exist on Docker Hub.

Sample warning

⚠️  WARNING: No Docker image exists for PHP 7.1 generation 5.
   Falling back to devwithlando/pantheon-appserver:7.1-4.
   For best results, use a Pantheon-recommended PHP version: 8.2, 8.3, 8.4.

Testing

  • Lint passes clean
  • 26-combination audit: every (php_version, php_runtime_generation) pair verified to resolve to a published Docker Hub tag

Note

Medium Risk
Changes how php_version and php_runtime_generation are normalized and resolved into Docker image tags, which can alter the selected appserver image at runtime. Risk is mitigated by explicit warnings plus new unit tests and a CI example covering the failure case.

Overview
Prevents the cryptic Docker manifest unknown failure by validating requested php_version + php_runtime_generation against a new map of published devwithlando/pantheon-appserver tags, warning users and falling back to the highest available generation when needed (or warning that no images exist for that PHP version).

Generalizes PHP version normalization so unquoted x.0 values from YAML are handled consistently, and reuses the same resolveGeneration logic inside the pantheon-php builder as a silent safety net.

Adds unit tests for the new resolution/warning behavior, plus a new examples/pantheon-php-warning Leia test fixture and includes it in the PR workflow matrix; updates the changelog to document the fix.

Reviewed by Cursor Bugbot for commit d60fdec. Bugbot is set up for automated code reviews on this repo. Configure here.

@netlify

netlify Bot commented Mar 23, 2026

Copy link
Copy Markdown

Deploy Preview for lando-pantheon ready!

Name Link
🔨 Latest commit d60fdec
🔍 Latest deploy log https://app.netlify.com/projects/lando-pantheon/deploys/69ed18582cccd20008ae0995
😎 Deploy Preview https://deploy-preview-348--lando-pantheon.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 90 (🔴 down 3 from production)
Accessibility: 98 (no change from production)
Best Practices: 100 (no change from production)
SEO: 92 (no change from production)
PWA: -
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Autofix Details

Bugbot Autofix prepared fixes for all 3 issues found in the latest run.

  • ✅ Fixed: Fallback to generation 4 instead of PHP 8.3 fails
    • Changed fallback logic to set data.php to DEFAULT_PHP_VERSION ('8.3') instead of changing data.generation to '4', ensuring the image tag uses 8.3-5 which exists on Docker Hub.
  • ✅ Fixed: Duplicated PHP version lists risk going out of sync
    • Exported SUPPORTED_PHP_VERSIONS from utils.js and updated pantheon-php.js to use utils.SUPPORTED_PHP_VERSIONS, eliminating the duplicate constant.
  • ✅ Fixed: YAML-parsed PHP 8.0 incorrectly flagged as unsupported
    • Added normalization in getPantheonConfig to convert '8' to '8.0' and '7' to '7.0' before the version check, preventing false positives when js-yaml parses 8.0 as the number 8.

Create PR

Or push these changes by commenting:

@cursor push 09d1df49e0
Preview (09d1df49e0)
diff --git a/builders/pantheon-php.js b/builders/pantheon-php.js
--- a/builders/pantheon-php.js
+++ b/builders/pantheon-php.js
@@ -5,9 +5,6 @@
 const LandoPhp = require('@lando/php/builders/php.js');
 const utils = require('./../lib/utils.js');
 
-// PHP versions that have generation 5 images; older versions top out at generation 4
-const SUPPORTED_PHP_VERSIONS_GEN5 = ['8.0', '8.1', '8.2', '8.3', '8.4'];
-
 // Builder
 module.exports = {
   name: 'pantheon-php',
@@ -25,7 +22,7 @@
       if (options.php === '8' || options.php === 8) options.php = '8.0';
 
       // Safety check: fall back to generation 4 if the php+generation combo has no image
-      if (options.generation === '5' && !SUPPORTED_PHP_VERSIONS_GEN5.includes(String(options.php))) {
+      if (options.generation === '5' && !utils.SUPPORTED_PHP_VERSIONS.includes(String(options.php))) {
         options.generation = '4';
       }
 

diff --git a/lib/utils.js b/lib/utils.js
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -218,6 +218,8 @@
 const SUPPORTED_PHP_VERSIONS = ['8.0', '8.1', '8.2', '8.3', '8.4'];
 const DEFAULT_PHP_VERSION = '8.3';
 
+exports.SUPPORTED_PHP_VERSIONS = SUPPORTED_PHP_VERSIONS;
+
 exports.getPantheonConfig = (files = ['pantheon.upstream.yml', 'pantheon.yml']) => _(files)
   .filter(file => fs.existsSync(file))
   .map(file => yaml.load(fs.readFileSync(file)))
@@ -225,6 +227,9 @@
   .thru(data => {
     // Set the php version
     data.php = _.toString(_.get(data, 'php_version', DEFAULT_PHP_VERSION));
+    // Normalize because 7.0/8.0 right away gets handled strangely by js-yaml
+    if (data.php === '7') data.php = '7.0';
+    if (data.php === '8') data.php = '8.0';
     // Set the webroot
     data.webroot = (_.get(data, 'web_docroot', false)) ? 'web' : '.';
     // Set the drush version
@@ -234,14 +239,14 @@
     // @DEPRECATED: Pantheon php_runtime_generation: 1 is deprecated and will be removed April 2026.
     const phpRuntimeGen = _.get(data, 'php_runtime_generation', 2);
     data.generation = phpRuntimeGen === 1 ? '4' : '5';
-    // Warn and fall back to generation 4 if the configured PHP version has no generation 5 image
+    // Warn and fall back to PHP 8.3 if the configured PHP version has no generation 5 image
     if (data.generation === '5' && !SUPPORTED_PHP_VERSIONS.includes(data.php)) {
       console.warn([
         `\n⚠️  WARNING: PHP ${data.php} does not have a generation 5 image.`,
-        `   Falling back to the generation 4 image (devwithlando/pantheon-appserver:${data.php}-4).`,
+        `   Falling back to PHP ${DEFAULT_PHP_VERSION} for this build.`,
         `   Consider updating php_version in your pantheon.yml to a supported version: ${SUPPORTED_PHP_VERSIONS.join(', ')}\n`,
       ].join('\n'));
-      data.generation = '4';
+      data.php = DEFAULT_PHP_VERSION;
     }
     // Set the tika version if specified in pantheon.yml
     const tikaVersion = _.get(data, 'tika_version');

Comment thread lib/utils.js Outdated
Comment thread builders/pantheon-php.js Outdated
Comment thread lib/utils.js
@AaronFeledy AaronFeledy force-pushed the fix/unsupported-php-version-warning branch 3 times, most recently from bcd9da0 to 3fe57e4 Compare April 25, 2026 02:52

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: JSDoc block detached from its target function
    • Moved constant declarations above the JSDoc block so it now correctly documents the getPantheonConfig function.

Create PR

Or push these changes by commenting:

@cursor push 501feb83fd
Preview (501feb83fd)
diff --git a/lib/utils.js b/lib/utils.js
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -209,11 +209,6 @@
   },
 };
 
-/**
- * Merges and processes Pantheon YAML configuration files
- * @param {string[]} [files=['pantheon.upstream.yml', 'pantheon.yml']] - YAML files to process
- * @return {Object} Merged configuration object
- */
 // PHP versions that have generation 5 images on Docker Hub.
 // Older versions (5.x, 7.0, 7.1) only have gen4 or earlier images.
 const SUPPORTED_PHP_VERSIONS = ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'];
@@ -222,6 +217,11 @@
 // Exported so the builder can reuse the same list and avoid drift
 exports.SUPPORTED_PHP_VERSIONS = SUPPORTED_PHP_VERSIONS;
 
+/**
+ * Merges and processes Pantheon YAML configuration files
+ * @param {string[]} [files=['pantheon.upstream.yml', 'pantheon.yml']] - YAML files to process
+ * @return {Object} Merged configuration object
+ */
 exports.getPantheonConfig = (files = ['pantheon.upstream.yml', 'pantheon.yml']) => _(files)
   .filter(file => fs.existsSync(file))
   .map(file => yaml.load(fs.readFileSync(file)))

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit 3fe57e4. Configure here.

Comment thread lib/utils.js Outdated
When users have php_version set to a version Pantheon no longer publishes
gen5 images for (e.g. 7.1) — or other invalid combinations — they got a
cryptic Docker error:

  appserver Error manifest for devwithlando/pantheon-appserver:7.1-5
  not found: manifest unknown

The fix validates the (php_version, php_runtime_generation) combination
against the set of images actually published on Docker Hub, and falls
back to a working generation when possible (in either direction). It
also emits a user-facing warning explaining what happened and pointing
at currently-recommended PHP versions.

Specifically handles:

* PHP version with no gen5 image (5.6, 7.0, 7.1) → falls back to gen4
* PHP 8.4 with deprecated 'php_runtime_generation: 1' → falls back to gen5
  (8.4 has no gen4 image)
* Very old PHP (5.3, 5.5) → falls back to gen2
* PHP versions with no images at all (e.g. typos, future versions) → emits
  a strong warning before the inevitable manifest error

Implementation notes:

* lib/utils.js: replaced ad-hoc SUPPORTED_PHP_VERSIONS list with a single
  PHP_GENERATION_IMAGES map that mirrors the published Docker Hub tags.
  Added a resolveGeneration() helper used by both getPantheonConfig and
  the builder. Added RECOMMENDED_PHP_VERSIONS to advise users in warnings
  (currently 8.2, 8.3, 8.4 per Pantheon's support policy).

* lib/utils.js: generalized PHP version normalization to handle any
  unquoted x.0 in YAML (was hard-coded for 7 and 8). js-yaml parses
  'php_version: 8.0' as the integer 8 since 8.0 === 8 in JS, which
  caused PHP 8.0 users to get a spurious warning + silent gen downgrade.

* lib/utils.js: moved new constants into the existing top-of-file
  Constants section so the JSDoc above getPantheonConfig stays attached
  to the function it documents.

* builders/pantheon-php.js: replaced the duplicated supported-versions
  list with a call to utils.resolveGeneration() — single source of truth.
@AaronFeledy AaronFeledy force-pushed the fix/unsupported-php-version-warning branch from 3fe57e4 to adf62d5 Compare April 25, 2026 03:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

appserver Error manifest for devwithlando/pantheon-appserver:7.1-5 not found: manifest unknown: manifest unknown

1 participant