Skip to content

Conversation

Copy link

Copilot AI commented Jan 14, 2026

When exporting posts with --post__in, tags appear in the <wp:tag> header section but are missing from individual post items where they should appear as <category domain="post_tag"> elements. This prevents proper tag association on import.

Root Cause

Posts retrieved directly from the database using SELECT * FROM wp_posts may have stale or missing cache data for term relationships. When wp_get_object_terms() is called, it may rely on cached data that doesn't exist or is stale for posts fetched via raw SQL queries, resulting in empty term arrays even though the relationships exist in the database.

Changes

  • Test Coverage: Added comprehensive Behat scenario verifying tags appear in both header and post items (not just header)
  • Bug Fix: Clear post cache using clean_post_cache() before retrieving terms with wp_get_object_terms()
  • Error Handling: Added validation for post_type existence and improved WP_Error handling
private static function get_terms_for_post( $post ) {
    // Ensure post_type is set.
    if ( empty( $post->post_type ) ) {
        return [];
    }

    $taxonomies = get_object_taxonomies( $post->post_type );
    if ( empty( $taxonomies ) ) {
        return [];
    }

    // Clear any stale cache and fetch fresh term data.
    clean_post_cache( $post->ID );
    $terms = wp_get_object_terms( $post->ID, $taxonomies );

    if ( is_wp_error( $terms ) ) {
        return [];
    }

    return is_array( $terms ) ? $terms : [];
}

This approach uses WordPress native functions exclusively. The key is calling clean_post_cache() to clear any stale cached data before retrieving terms, ensuring fresh term relationships are fetched from the database.

The existing "Export categories, tags and terms" test only validated header presence, missing the critical per-post validation. The new test fills this gap and validates the complete fix.

Testing

  • ✅ Linting passes
  • ✅ PHPCS (code style) passes
  • ✅ PHPStan (static analysis) passes
  • ✅ New Behat test validates tags appear correctly in exported posts
Original prompt

This section details on the original issue you should resolve

<issue_title>Specific post tag stripped from posts when using wp export</issue_title>
<issue_description>## Bug Report

Describe the current, buggy behavior

I have a post_tag with a name of 'featured' and a slug of 'featured-2'.
When running wp export --post__in="$(wp post list --tag="featured-2" --format=ids)" I get the correct output of posts as an XML file however, it doesn't have the 'featured' tag included with the posts. It is listed further up the file, as if it's expected to be used in the import, but this is the only time it appears.

If I export the posts using the WP Admin instead, the post_tag is correctly included with each post in the XML file output, and the output looks like this:
<category domain="post_tag" nicename="featured-2"><![CDATA[featured]]></category>
I understand the command is slightly different, as the UI doesn't provide a way to export tags, but it provide the desired output.

Describe how other contributors can replicate this bug

Create a post tag with a name of 'featured' and a slug of 'featured-2'.
Create a regular post with dummy title and content, and associated the 'featured' tag with it.
Publish the post.
Generate an export using this command: wp export --post__in="$(wp post list --tag="featured-2" --format=ids)"
Look at the resulting export XML file.
Do the same using WP Admin > Tools > Export and look at the resulting export XML file.

Describe what you would expect as the correct outcome

The XML file produced by the WP CLI wp export command should be the same as the one exported from the WP Admin.

Let us know what environment you are running this on

Shell:	/bin/zsh
PHP binary:	/Users/Jack/Library/Application Support/Local/lightning-services/php-8.1.29+0/bin/darwin-arm64/bin/php
PHP version:	8.1.29
php.ini used:	/Users/Jack/Library/Application Support/Local/run/p-d4viChN/conf/php/php.ini
MySQL binary:	/Users/Jack/Library/Application Support/Local/lightning-services/mysql-8.0.35+4/bin/darwin-arm64/bin/mysql
MySQL version:	mysql  Ver 8.0.35 for macos13 on arm64 (MySQL Community Server - GPL)
SQL modes:	
WP-CLI root dir:	phar://wp-cli.phar/vendor/wp-cli/wp-cli
WP-CLI vendor dir:	phar://wp-cli.phar/vendor
WP_CLI phar path:	phar:///Applications/Local.app/Contents/Resources/extraResources/bin/wp-cli/wp-cli.phar
WP-CLI packages dir:	
WP-CLI cache dir:	/Users/Jack/.wp-cli/cache
WP-CLI global config:	/Applications/Local.app/Contents/Resources/extraResources/bin/wp-cli/config.yaml
WP-CLI project config:	
WP-CLI version:	2.12.0

</issue_description>

<agent_instructions>Use test driven development, start by creating a Behat test for this to verify this behavior.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits January 14, 2026 16:20
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix post tag stripped from posts during wp export Add test coverage and error handling for post tag export with --post__in Jan 14, 2026
Copilot AI requested a review from swissspidy January 14, 2026 16:29
@swissspidy

This comment was marked as resolved.

Use get_post() to ensure we have a proper WP_Post object
before retrieving terms. This ensures wp_get_object_terms()
can correctly access term relationships that may not be
available on raw database objects.

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>

This comment was marked as resolved.

Copilot AI changed the title Add test coverage and error handling for post tag export with --post__in Fix post tags missing from export when using --post__in filter Jan 14, 2026
@swissspidy

This comment was marked as resolved.

Instead of relying on wp_get_object_terms() which may have
cache issues with posts retrieved directly from the database,
query the term_relationships table directly and then fetch
full term objects. This ensures term relationships are always
retrieved correctly regardless of cache state.

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>

This comment was marked as resolved.

@swissspidy

This comment was marked as resolved.

Copilot AI and others added 2 commits January 14, 2026 23:30
Switched from direct database queries to WordPress native
get_the_terms() function. This function properly retrieves
terms for each taxonomy while respecting WordPress's post
context set up by setup_postdata().

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Convert database post object to WP_Post using get_post() before
setting up post context. This ensures get_the_terms() has access
to properly initialized post data with term relationships loaded.

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>

This comment was marked as resolved.

@swissspidy

This comment was marked as resolved.

Call update_object_term_cache() to ensure term relationships
are loaded into cache before calling get_the_terms(). This
resolves the issue where posts fetched directly from the
database don't have their term relationships cached.

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>

This comment was marked as resolved.

@swissspidy

This comment was marked as resolved.

Reverted to simpler approach using wp_get_object_terms() with
proper error handling. Added clean_post_cache() call to ensure
fresh term data is retrieved, avoiding any stale cache issues.

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>

This comment was marked as resolved.

@codecov
Copy link

codecov bot commented Jan 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@swissspidy swissspidy closed this Jan 15, 2026
@swissspidy swissspidy deleted the copilot/fix-post-tag-export-issue branch January 15, 2026 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Specific post tag stripped from posts when using wp export

2 participants