Skip to content

Fix featured image rename failure on servers with .tmp in temp directory path#1256

Open
Copilot wants to merge 3 commits into
developmentfrom
copilot/fix-featured-image-renaming-bug
Open

Fix featured image rename failure on servers with .tmp in temp directory path#1256
Copilot wants to merge 3 commits into
developmentfrom
copilot/fix-featured-image-renaming-bug

Conversation

Copilot AI commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

try_save_featured_image() used str_replace('.tmp', ...) to swap the downloaded file's .tmp extension for the real MIME extension. On servers where the system temp directory itself contains .tmp in its path (e.g. /usr/home/user/.tmp/), this corrupts the directory segment too — producing a path like /usr/home/user/.jpeg/file.jpeg — causing rename() to fail for every import.

Change

  • includes/admin/feedzy-rss-feeds-import.php — replace str_replace with an end-anchored preg_replace so only the .tmp file extension is rewritten, and use wp_get_default_extension_for_mime_type() for safer extension derivation that handles all MIME types (not just image/*):
// Before — replaces ALL occurrences of ".tmp" in the full path string
$new_local_file = str_replace( '.tmp', str_replace( 'image/', '.', $type ), $local_file );

// After — replaces only a trailing ".tmp" extension, with a properly derived extension
$extension      = function_exists( 'wp_get_default_extension_for_mime_type' ) ? wp_get_default_extension_for_mime_type( $type ) : '';
$extension      = ! empty( $extension ) ? '.' . $extension : str_replace( 'image/', '.', $type );
$new_local_file = preg_replace( '/\.tmp$/', $extension, $local_file );

Using wp_get_default_extension_for_mime_type() ensures non-image MIME types (e.g. application/pdf) also get a valid file extension, matching the same pattern already used earlier in this method.

Copilot AI changed the title [WIP] Fix bug in try_save_featured_image affecting temporary file renaming Fix featured image rename failure on servers with .tmp in temp directory path Jun 11, 2026
Copilot AI requested a review from poonam279 June 11, 2026 08:20

Copilot AI 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.

Pull request overview

Fixes a featured-image import failure caused by rewriting .tmp anywhere in the downloaded temp file path (including directory segments like /.tmp/) by only rewriting a trailing .tmp extension.

Changes:

  • Replace the .tmp extension rewrite from str_replace() to an end-anchored preg_replace('/\.tmp$/', ...) in try_save_featured_image(), preventing path corruption when temp directories include .tmp.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// so let's determine the file's mime type and then rename the .tmp file with that extension.
if ( in_array( $type, array_values( get_allowed_mime_types() ), true ) ) {
$new_local_file = str_replace( '.tmp', str_replace( 'image/', '.', $type ), $local_file );
$new_local_file = preg_replace( '/\.tmp$/', str_replace( 'image/', '.', $type ), $local_file );
@poonam279

Copy link
Copy Markdown

@Soare-Robert-Daniel, I'm not sure which solution would be the best one here. Could you please review Copilot's suggestion and confirm whether it looks correct?

@Soare-Robert-Daniel

Copy link
Copy Markdown
Contributor

@claude[agent] evalue the current solution based on the original problem

Description
When importing posts (e.g. from YouTube feeds) with Feedzy, featured images are sometimes not attached, and import logs show repeated errors like:

Could not rename temporary file for: [post title]

Expectation:
Featured images should be saved and attached for imported posts as expected on all systems that support file operations.

Current Behavior:
On certain servers, particularly those where the WordPress temp folder path contains a directory named ".tmp" (e.g., /usr/home/user/.tmp/), the file rename involved in saving an image fails. This is due to a code bug that replaces .tmp anywhere in the full temp file path, causing the function to attempt a rename the parent directory (which doesn't exist), instead of only replacing the file extension. On environments where the temp directory is /tmp/, the bug does not occur and image saving works fine.

Related code: includes/admin/feedzy-rss-feeds-import.php::try_save_featured_image()

See explanation and fix below.

Step-by-step reproduction instructions
Set up Feedzy on a server or container where PHP's temp directory (sys_get_temp_dir()) uses a parent folder named .tmp (for example, /usr/home/USERNAME/.tmp/).

Configure an import job that pulls posts with images (e.g., a YouTube feed).

Run the import job.

Observe that imported posts are missing featured images and the error log contains repeated entries:

Could not rename temporary file for: [post title]

If moving to a different server with /tmp/ as the temp directory (no dot-prefix), the import works as expected.

Screenshots, screen recording, code snippet or Help Scout ticket
Error screenshot with logs and JSON context:

Feedzy featured image rename error screenshot
Code snippet causing the problem:
in includes/admin/feedzy-rss-feeds-import.php:

// Before (buggy)
$new_local_file = str_replace('.tmp', str_replace('image/', '.', $type), $local_file);
// After (fixed)
$new_local_file = preg_replace('/\.tmp$/', str_replace('image/', '.', $type), $local_file);
See also: error message context, code references, and changelog notes about related improvements.


…vation

Agent-Logs-Url: https://github.com/Codeinwp/feedzy-rss-feeds/sessions/c9e20d0d-b601-4ecc-84ef-267703743c41

Co-authored-by: Soare-Robert-Daniel <17597852+Soare-Robert-Daniel@users.noreply.github.com>
@Claude

Claude AI commented Jun 12, 2026

Copy link
Copy Markdown

@claude[agent] evalue the current solution based on the original problem

...

The current solution correctly addresses the original problem. The fix has two parts:

  1. preg_replace('/\.tmp$/', ...) — end-anchored regex ensures only the trailing .tmp file extension is replaced, never a .tmp directory component in the path (e.g., /usr/home/user/.tmp/file.tmp → only the last .tmp is replaced).

  2. wp_get_default_extension_for_mime_type() — addresses the reviewer's concern about non-image MIME types. Instead of relying solely on str_replace('image/', '.', $type) which only works for image/* types, we use the WordPress API to derive the correct extension for any allowed MIME type. This matches the same pattern already used at lines 3159-3160 in this method.

The str_replace('image/', '.', $type) is kept only as a fallback for defensive compatibility, but in practice it won't be reached since wp_get_default_extension_for_mime_type() handles all types registered via get_allowed_mime_types().

See commit 361f006.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/Automattic/VIP-Coding-Standards/zipball/2b1d206d81b74ed999023cffd924f862ff2753c8
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kMPoPy /usr/bin/composer install --quiet git copilot.originalgit (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/hsQm6c /usr/bin/composer install --no-scripts --no-plugins (http block)
  • https://api.github.com/repos/Codeinwp/themeisle-sdk/zipball/d1ae68cbd4f84934b4d982e9eeff317b9f4c814a
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kMPoPy /usr/bin/composer install --quiet git copilot.originalgit (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/hsQm6c /usr/bin/composer install --no-scripts --no-plugins (http block)
  • https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/fa4b8d051e278072928e32d817456a7fdb57b6ca
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kMPoPy /usr/bin/composer install --quiet git copilot.originalgit (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/hsQm6c /usr/bin/composer install --no-scripts --no-plugins (http block)
  • https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/65355670ac17c34cd235cf9d3ceae1b9252c4dad
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kMPoPy /usr/bin/composer install --quiet git copilot.originalgit (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/hsQm6c /usr/bin/composer install --no-scripts --no-plugins (http block)
  • https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5b5e3821314f947dd040c70f7992a64eac89025c
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kMPoPy /usr/bin/composer install --quiet git copilot.originalgit (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/hsQm6c /usr/bin/composer install --no-scripts --no-plugins (http block)
  • https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kMPoPy /usr/bin/composer install --quiet git copilot.originalgit (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/hsQm6c /usr/bin/composer install --no-scripts --no-plugins (http block)
  • https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/293975b465e0e709b571cbf0c957c6c0a7b9a2ac
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/5bfbbfbabb3df2b9a83e601de9153e4a7111962c
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/d2421de7cec3274ae622c22c744de9a62c7925af
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kMPoPy /usr/bin/composer install --quiet git copilot.originalgit (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/hsQm6c /usr/bin/composer install --no-scripts --no-plugins (http block)
  • https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/134921bfca9b02d8f374c48381451da1d98402f9
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/92e444847d94f7c30f88c60004648f507688acd5
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/phpstan/phpstan/zipball/3a6e423c076ab39dfedc307e2ac627ef579db162
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dc7ceb4a24aede938c7af2a9ed1de09609ca770
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/diff/zipball/98ff311ca519c3aa73ccd3de053bdb377171d7b6
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/environment/zipball/56932f6049a0482853056ffd617c91ffcc754205
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/exporter/zipball/1939bc8fd1d39adcfa88c5b35335910869214c56
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/global-state/zipball/91c7c47047a971f02de57ed6f040087ef110c5d9
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/ac5b293dba925751b808e02923399fb44ff0d541
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/1d439c229e61f244ff1f211e5c99737f90c67def
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/40a4ed114a4aea5afd6df8d0f0c9cd3033097f66
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/69deeb8664f611f156a924154985fbd4911eb36b
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/php-timer/zipball/a691211e94ff39a34811abd521c31bd5b305b0bb
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9c1da83261628cb24b6a6df371b6e312b3954768
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d843cb5bcf0bf9ae3484016444fe0c5b6ec7e4fa
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/9bfd3c6f1f08c026f542032dfb42813544f7d64c
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/72a7f7674d053d548003b16ff5a106e7e0e06eee
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/type/zipball/18f071c3a29892b037d35e6b20ddf3ea39b42874
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/4debf5383d9ade705e0a25121f16c3fecaf433a7
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/kMPoPy /usr/bin/composer install --quiet git copilot.originalgit (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/hsQm6c /usr/bin/composer install --no-scripts --no-plugins (http block)
  • https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/szepeviktor/phpstan-wordpress/zipball/7f8cfe992faa96b6a33bbd75c7bace98864161e7
    • Triggering command: REDACTED, pid is -1 (http block)
  • https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2
    • Triggering command: REDACTED, pid is -1 (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@Soare-Robert-Daniel Soare-Robert-Daniel marked this pull request as ready for review June 12, 2026 10:21
@pirate-bot

Copy link
Copy Markdown
Contributor

Plugin build for 361f006 is ready 🛎️!

Note

You can preview the changes in the Playground

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cannot rename temporary file for featured image: bug in try_save_featured_image() affects certain server paths

6 participants