"This Edit has been deleted": why Google Play edits expire mid-upload

This Edit has been deleted means the edit you were writing into no longer exists on Google's side. Something else changed the app while your edit was open, and Google threw yours away.

You will usually see it wrapped in an HTTP 400 from the Play Developer API, on a call to something under /edits/{editId}/. The listing update, the image upload or the track assignment never landed. Nothing is broken about your app or your bundle.

The fix is always the same: open a fresh edit and do the work again. Retrying the same editId cannot work, because that id is now meaningless.

What an edit actually is

The Play Developer API has no direct write endpoints. Everything goes through an edit: you insert an edit, make your changes inside it, then commit. Google's documentation is explicit that nothing takes effect until you do: "Changes made within an edit are not live until the edit is committed."

An edit is a transaction with no locking and a very blunt conflict policy. Three sentences from Google's own docs describe the whole failure mode:

"Each user may have only a single edit open at a time. If you create a new edit, any existing edit you may have open is invalidated."

"If anyone commits an edit or makes changes to an app through the Play Console, all other edits for the app (owned by any user) are invalidated."

"If anyone makes any changes to the app through the Google Play Console while you have an edit in progress, your edit is discarded and the Play Console changes take effect."

Read the second one again. Not your edits. All edits, owned by any user. One person saving a typo fix in the console kills every automated pipeline currently mid-write on that app.

The race condition that costs real releases

The nastiest version of this has nothing to do with a human in the console.

Uploading an Android App Bundle is slow. A large AAB takes minutes, and it has to be uploaded inside an open edit. During those minutes, anything that opens a second edit on the same app invalidates the first one, and the upload you are part way through becomes worthless.

The usual culprit is your own tooling. A status poller that reads the current tracks has to open an edit to do it, because reads go through edits too. Poll every fifteen minutes, upload a 300 MB bundle, and eventually the two collide. The upload streams to completion, the commit fails, and the error you get names the edit rather than the cause.

Other reliable ways to hit it:

  • Two CI jobs for the same package running at once, for example a listing push and a release upload
  • A cron job that syncs metadata while a deploy is running
  • A teammate opening the app in Play Console during the deploy window and saving anything
  • Two tools connected to the same service account, each opening edits on its own schedule
  • A retry that opens a new edit while the original request is still in flight

How long does an edit last?

Google does not publish a lifetime. The docs describe invalidation by conflict and say nothing about a timer.

You will see "edits expire after 24 hours" repeated in forum answers and blog posts. Treat that as folklore unless you can find it in Google's documentation, because it is not there.

What is safe to assume: an edit lives as long as nothing else touches the app, and no longer. Design for invalidation at any moment rather than for a deadline.

Avoiding it

One writer per app. Pick a single system that opens edits for a given package and make everything else go through it. Two tools with edit access to one app will collide eventually; it is a matter of traffic, not luck.

Never open a read edit during a write. If you have a poller or an importer that opens edits to read state, gate it on whether a delivery is running for that app. Serve the cached state instead and catch up on the next cycle. A stale tracks list is a cosmetic problem. A killed AAB upload is a lost release.

Keep edits short. Open the edit, do the work, commit, and get out. An edit held open while your code does something slow and unrelated is a window for someone else to break it.

Tell people not to touch the console. Unglamorous, and the single highest-value rule on a small team. During a deploy, Play Console is read-only by agreement.

Retry from scratch, not from the id. On failure, open a new edit, redo the work, commit. Any retry logic that reuses the failed editId will fail forever.

Do the uploads first. Upload the bundle, then set the listing, then assign the track, then commit. The long operation is the vulnerable one, so give it the freshest possible edit.

The other edits errors

This Edit has been deleted is the most common but not the only one. Anything in the 4xx range on an /edits/ path is worth reading carefully, because the API uses the same shape of error for very different causes:

  • Edit gone or invalidated: open a fresh one and redo the work
  • Service account lost its role: the call is refused rather than the edit being stale, and re-checking the connection will not help until the permission is restored
  • Commit refused because changes cannot be auto-sent for review: Google asks for changesNotSentForReview=true, and the changes land as a draft in the console instead

Those three want different responses, and only the first is fixed by retrying.

What good handling looks like

A failed edit should never leave a user guessing. The honest sequence is: recognise the error, say that the edit went stale rather than printing the raw string, open a fresh edit, replay the same work, and only involve a human if the second attempt fails for a different reason.

AppSubmit does that, and blocks its own listing reads and status polls while a Play delivery is in flight, because that specific collision killed a bundle upload once and the cached tracks list was never worth it. You can enforce the same rule in your own pipeline with a lock around the package name.

Read next

Last reviewed 2026-08-17. Apple and Google change their rules without notice, so check anything decision-critical against their live documentation.