Skip to content

Secondary networks: sunrise queries unregistered scoped tables, and wu_{N}_* tables are never created #2012

Closed

Description

@superdav42

Problem

On a multi-network install, Ultimate Multisite queries network-scoped tables ({base_prefix}wu_{network_id}_*) on secondary networks, but two paths leave those tables unusable:

  1. Sunrise domain mapping queries tables that were never registered. Sunrise::load_domain_mapping() (inc/class-sunrise.php:191-205) starts Domain_Mapping on every network. On a network where Ultimate Multisite returns before setup_tables() (inc/class-wp-ultimo.php, the Requirements::met() === false || Requirements::run_setup() === false early return; run_setup() reads the per-network wu_setup_finished option), no Table object is built for that network. The domain Query still applies the network prefix (Network_Prefix::update_prefix_with_network_id(), inc/database/engine/traits/trait-network-prefix.php:20-25), so it reads $wpdb->wu_{N}_domain_mappings. That property is unset, which gives an empty table name:

    Table '<db>.wu_5_d' doesn't exist for query SELECT  wu_5_d.id FROM  wu_5_d WHERE wu_5_d.blog_id = 323 AND wu_5_d.domain != ...
    

    Note the double space: the table name is empty and only the alias wu_5_d remains. Production logged about 170 of these in 7 hours on one template network.

  2. Secondary-network tables are never created. Table::is_upgradeable() (inc/database/engine/class-table.php:50-57) returns false unless the request is on the main network and main site, so maybe_upgrade() never installs wp_wu_{N}_*. A network ends up with none of these tables, or with only the subset some one-off path created. One network had customers/memberships/payments but no posts, postmeta, webhooks, passkey_credentials, webauthn_challenges, email_otp_attempts or sso_nonces. Addon tables that extend the core Table (e.g. metered-plans' metered_usage) inherit the same gap. A missing posts table also means a network has no system emails (payment_received_*, site_published_*, …).

Expected

  • Every secondary network that Ultimate Multisite serves has its full set of scoped tables, created idempotently when the network is first used or created, and on upgrade.
  • Domain mapping at sunrise never builds a query against an unregistered table. Either register the network's tables (e.g. build the needed Table objects in Sunrise::load_domain_mapping() before Domain_Mapping runs), or fall back to the main network's tables when Ultimate Multisite is not set up on the current network.
  • Default system emails get created for a network once its posts table exists.

Workaround applied on one install (not a fix)

Ran in each affected network's --url context:

  • $t->install() for every Table_Loader::get_instance()->get_tables() entry, plus Metered_Usage_Table, where exists() was false.
  • Email_Manager::get_instance()->create_all_system_emails().
  • For the template network, set the wu_setup_finished network option so Ultimate Multisite completes loading and registers its tables.

Note: Table::exists() caches its result, so in the same process it still reported false right after a successful install(). A fresh process or information_schema showed the tables were present.

Files to modify

  • inc/class-sunrise.php (load_domain_mapping)
  • inc/database/engine/class-table.php (is_upgradeable, and possibly the exists() cache)
  • inc/installers/class-core-installer.php (network-scoped install)
  • inc/loaders/class-table-loader.php
  • inc/managers/class-email-manager.php (create_all_system_emails on new networks)

Verification

On a multi-network test install:

  1. Create a secondary network without running the setup wizard and request one of its mapped domains. There should be no FROM wu_N_ (empty table) errors.
  2. Every get_tables() entry should exists() for that network after creation or upgrade.
  3. wu_get_emails() should return the default system emails on that network.

Files Scope

  • inc/class-sunrise.php
  • inc/database/engine/class-table.php
  • inc/installers/class-core-installer.php
  • inc/loaders/class-table-loader.php
  • inc/managers/class-email-manager.php
  • tests/WP_Ultimo/Database/Engine/Table_Test.php
  • tests/WP_Ultimo/Managers/Email_Manager_Test.php

aidevops.sh v3.39.49 plugin for OpenCode

Activity

  1. self-assigned this
    on Oct 21, 2026
  2. removed their assignment
    on Oct 21, 2026
  3. superdav42 commented on Oct 21, 2026

    @superdav42
    CollaboratorAuthor

    DISPATCH_CLAIM nonce=a50fd5e1f314c84f826f2aa01722ab19 runner=superdav42 ts=2026-10-21T15:19:36Z max_age_s=1800 version=3.39.49 opencode_version=1.18.31 lease_token=a50fd5e1f314c84f826f2aa01722ab19 device=device-1783824528-2609248-26808 session=issue-2012 phase=prelaunch expires_at=1792596098

  4. superdav42 commented on Oct 21, 2026

    @superdav42
    CollaboratorAuthor

    DISPATCH_LEASE phase=prelaunch lease_token=a50fd5e1f314c84f826f2aa01722ab19 device=device-1783824528-2609248-26808 session=issue-2012 expires_at=1792596444 ts=2026-10-21T15:19:54Z attempt_id=attempt:5d33ba6b-18fb-48eb-87c5-0ddfb5206c88

  5. locked as resolved and limited conversation to collaborators on Oct 21, 2026
  6. added
    status:queuedWorker dispatched, not yet started
    and removed
    status:queuedWorker dispatched, not yet started
    on Oct 21, 2026
  7. superdav42 commented on Oct 21, 2026

    @superdav42
    CollaboratorAuthor

    Dispatching worker (deterministic).

  8. superdav42 commented on Oct 21, 2026

    @superdav42
    CollaboratorAuthor

    DISPATCH_LEASE phase=ready lease_token=a50fd5e1f314c84f826f2aa01722ab19 device=device-1783824528-2609248-26808 session=issue-2012 expires_at=1792603240 ts=2026-10-21T15:20:40Z attempt_id=attempt:5d33ba6b-18fb-48eb-87c5-0ddfb5206c88


    aidevops.sh v3.39.49 automated scan.

  9. 10 remaining items

  10. added
    status:queuedWorker dispatched, not yet started
    and removed
    status:queuedWorker dispatched, not yet started
    on Oct 22, 2026
  11. superdav42 commented on Oct 22, 2026

    @superdav42
    CollaboratorAuthor

    Dispatching worker (deterministic).

  12. superdav42 commented on Oct 22, 2026

    @superdav42
    CollaboratorAuthor

    DISPATCH_LEASE phase=ready lease_token=65099c0ff81aef1f1aa95b215fdb6324 device=device-1783824528-2609248-26808 session=issue-2012 expires_at=1792693444 ts=2026-10-22T16:24:04Z attempt_id=attempt:5f8ed951-2070-4737-baf3-5699fd22b715


    aidevops.sh v3.39.49 automated scan.

  13. unlocked this conversation on Oct 22, 2026
  14. added
    status:in-reviewNon-draft PR ready for review/merge
    and removed on Oct 22, 2026
  15. superdav42 commented on Oct 22, 2026

    @superdav42
    CollaboratorAuthor

    CLAIM_RELEASED reason=worker_complete runner=superdav42 ts=2026-10-22T16:33:23Z aidevops_version=3.39.49 opencode_version=1.18.31


    aidevops.sh v3.39.49 plugin for OpenCode v1.18.31

  16. superdav42 commented on Oct 22, 2026

    @superdav42
    CollaboratorAuthor

    DISPATCH_LEASE phase=terminal lease_token=65099c0ff81aef1f1aa95b215fdb6324 device=device-1783824528-2609248-26808 session=issue-2012 expires_at=0 ts=2026-10-22T16:33:39Z attempt_id=attempt:5f8ed951-2070-4737-baf3-5699fd22b715


    aidevops.sh v3.39.49 automated scan.

  17. added a commit that references this issue on Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingorigin:interactiveCreated by interactive user sessionstatus:in-reviewNon-draft PR ready for review/merge

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions