Automattic / Automattic/studio

Push causes temporary fatal errors on the production site if plugin is partially copied

Open
#4,738 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
517
Forks
95
Avg merge
1d 23h
Merged PRs (30d)
172

Description

### Quick summary

During a push ("All files and folders" + "Database") to a WordPress.com Atomic production site, files are synced into the live docroot non-atomically while the site continues to serve traffic and while the remote database-import helper runs.

If an *active* plugin is only partially copied at the moment WordPress boots (main plugin file present, required subfiles not yet copied), every WordPress bootstrap fatals — including the Jetpack/VaultPress import helper — so the DB import fails and Studio reports the generic "The database failed to import on the live site." Live visitors during that window get 500s.

### Steps to reproduce

1. Connect a Studio site (with several active plugins) to a WordPress.com Atomic production site.
2. Push with "All files and folders" + "Database".
3. During the file-sync window, the production PHP error log records a fatal for an active plugin whose directory is mid-copy (main file exists, includes missing).
4. The import helper (`wp-content/jetpack-temp/jp-helper-*.php`) bootstraps WordPress, hits the same fatal, returns HTTP 500, and the import is reported as failed.

Timing is racy — which plugin trips depends on when the helper bootstraps relative to extraction order.

### What you expected to happen

- File sync should be atomic with respect to WordPress bootstrap (extract to a staging path and swap), or the import helper should run with plugins suppressed, or the DB import should be sequenced so it never bootstraps against a half-copied tree.
- The remote PHP fatal should be surfaced in Studio instead of the generic DB error.

### What actually happened

```
PHP Fatal error: Uncaught Error: Failed opening required '/srv/htdocs/wp-content/plugins/code-snippets/php/load.php' (include_path='/:.') in [/srv/htdocs/wp-content/plugins/code-snippets/code-snippets.php](/srv/htdocs/wp-content/plugins/code-snippets/code-snippets.php):61
Stack trace:
#0 /wordpress/core/7.1/wp-settings.php(597): include_once()
#1 /srv/htdocs/wp-config.php(86): require_once('/wordpress/core...')
#2 /wordpress/core/7.1/wp-load.php(55): require_once('/srv/htdocs/wp-...')
#3 /wordpress/core/7.1/wp-blog-header.php(13): require_once('/wordpress/core...')
#4 /wordpress/core/7.1/index.php(17): require('/wordpress/core...')
#5 {main}
```

Web server logs (same window, UTC):

```
02:24:28 500 POST / (Jetpack by [WordPress.com](http://WordPress.com))
02:28:45 500 POST /wp-content/jetpack-temp/jp-helper-.php (Automattic/VaultPress/0.1)
```

Studio then fails at 02:34:50 with:

```
[2026-08-31T02:34:50.310Z][erro][main] Error occurred in handler for 'pushSiteToLive': Error: The database failed to import on the live site. Review your database and try again.
```

The local copy of the plugin is complete (`php/load.php` exists locally), and the production site recovered on its own once the file sync finished — confirming a transient mid-sync state rather than a broken upload.

Related observation: the push also replaced production's `/srv/htdocs/wp-config.php` with the local Studio copy. Studio appends local defines (e.g. `define( 'DB_NAME', 'wordpress' )`) to the wp-config pulled from Atomic, so after a push, production logs `PHP Warning: Constant DB_NAME already defined in /srv/htdocs/wp-config.php on line 76` on requests (Atomic auto-provides DB constants). Excluding `wp-config.php` from the push by default (or via docs guidance) would avoid this; `.deployignore` works as a manual fix.

### App or CLI?

Studio App

### Version

1.18.0

### Impact

One

### Available workarounds?

Yes, easy to implement

Deactivating the affected plugin on both production and the Studio site before pushing removes it from the bootstrap path.

### Platform

Mac

### Architecture

ARM64 (Apple Silicon, Windows or Linux on ARM)

### Logs or notes

- Studio 1.18.0 (production, commit 121b18d77f96e4362c7d22bdcd4c428022503f8b), macOS 26.6.1
- Remote: WordPress.com Atomic production site (~420 MB payload), WP core 7.1

Happy to provide the site URL / blog ID and exact timestamps privately for backend correlation.

Contributor guide

Open the contributing guide

Research direction

Start at the pushSiteToLive handler and trace how file synchronization and the remote database-import helper are sequenced; inspect the .deployignore handling for wp-config.php. Reproduce with an active plugin during a push, then verify that WordPress never boots against a partial tree and that remote PHP fatals are surfaced instead of reported as a generic database-import failure.

Written by the indexing model from the issue text.

Assessment

Tech stack
electron, php, typescript
Domain
cloud, desktop, devops
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.