Skip to content

fetchExternalData() fails on HTTP 201 response from hub-api.h5p.org/v1/sites #210

@ingnrcs

Description

@ingnrcs

Bug: fetchExternalData() fails silently on HTTP 201 response from hub-api.h5p.org — site registration broken on new installs

Description

On new WordPress installations, the H5P Hub registration fails completely and the plugin displays:

Site could not be registered with the hub. Please contact your site administrator.
The H5P Hub has been disabled until this problem can be resolved.

The Content Type Cache never updates (stays at Unix timestamp 0 / Jan 1, 1970) and no content types are available.

Root Cause

The hub-api.h5p.org/v1/sites endpoint now returns HTTP 201 Created for new site registrations instead of HTTP 200. However, fetchExternalData() in class-h5p-wordpress.php only accepts 200 as a success response — any other status code causes it to return NULL.

This means:

  1. H5P calls hub-api.h5p.org/v1/sites via POST
  2. The server responds with HTTP 201 + {"uuid": "..."}
  3. fetchExternalData() does not recognize 201 → returns NULL
  4. fetchLibrariesMetadata() evaluates if (!$registration) → NULL is falsy
  5. Plugin enters the error block → displays the failure message
  6. UUID is never saved → the cycle repeats on every admin page load, generating a new UUID each time

Steps to Reproduce

  1. Install H5P plugin on a fresh WordPress installation
  2. Go to H5P → Settings and enable the Hub
  3. Observe the "Site could not be registered" error
  4. Enable WP_DEBUG_LOG and add an http_response filter — you will see HTTP 201 responses from hub-api.h5p.org/v1/sites being silently discarded

Environment

  • Plugin version: 1.17.2
  • WordPress version: 6.9.1
  • PHP version: 8.x
  • Hosting: Hostinger (confirmed on multiple fresh installs)

Affected File

public/class-h5p-wordpress.php — method fetchExternalData()

Current Code (buggy)

elseif ($response['response']['code'] === 200) {
    return empty($response['body']) ? TRUE : $response['body'];
}
return NULL; // HTTP 201 falls here → returns NULL → treated as failure

Proposed Fix (one line change)

elseif ($response['response']['code'] === 200 || $response['response']['code'] === 201) {
    return empty($response['body']) ? TRUE : $response['body'];
}
return NULL;

Evidence

Debug log showing HTTP 201 received from hub-api.h5p.org/v1/sites while [uuid] remains empty in the next request (because it was never saved):

H5P INTERNAL REQUEST URL: https://hub-api.h5p.org/v1/sites
H5P INTERNAL REQUEST BODY: Array ( [uuid] =>  ... )
H5P INTERNAL RESPONSE CODE: 201
H5P INTERNAL RESPONSE BODY: {"uuid":"019cd7a5-a224-703e-b03d-d1321aec2cc6"}

// Next request — uuid is still empty:
H5P INTERNAL REQUEST BODY: Array ( [uuid] =>  ... )

Notes

  • This fix has been tested and confirmed working on a live site
  • The issue only affects new registrations (empty uuid). Existing registered sites are not impacted
  • The same pattern should be reviewed in other methods of fetchExternalData() that check for === 200 when communicating with hub-api.h5p.org

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions