HotCodePush

Results and reasons

Every status a HotCodePush sync returns, from up_to_date to skipped and failed, and every reason code with its meaning and what to do about it.

A sync resolves to one of seven statuses, and a skipped or failed status carries a reason, a code that reads as a sentence. The debug screen, the console, hotcodepush device probe and the typed result in the app print the same code for the same situation. Troubleshooting routes each one to its cause.

The statuses

StatusMeans
up_to_dateThere is nothing to do. release is the running release, or null on the embedded bundle.
availableA release this device can take is not downloaded yet. checkForUpdate() answers it, and sync() when downloadStrategy is manual.
downloadedThe update is downloaded and verified, waiting for its apply moment: next_start, next_resume, or a manual call to applyUpdate().
appliedThe apply happened, and the update becomes the current release as the app reloads.
nothing_to_applyapplyUpdate() found nothing waiting.
skippedThere is a newer release and this device will not take it now, and reason says why.
failedSomething went wrong on the way, and reason says what and message says it in words.

release is null where no release could be evaluated. On skipped it is the newest release the device will not take, except for release_revoked, where it is the release the device falls back to. The condition field names the condition type behind device_incompatible or device_not_targeted, one of binary, fingerprint, os, attribute and device, never a value.

The result types, the methods and the events are on the API page of each SDK.

Skipped reasons

A skip means the device evaluated a newer release and decided against it, and the next check evaluates again.

ReasonMeansWhat to do
build_debugA debug build has isEnabledInDebugBuilds off, or the build embeds no bundle, as a React Native or Expo debug build does.Test on a release build.
bundle_failed_beforeThis bundle failed on this device before and is not tried again here.Publish a new release, or call clearUpdates() on the device.
channel_pausedThe channel is paused and serves nothing new.Fix what the devices hit, then resume the channel: the pause.
condition_unsupportedThe release uses a condition type this SDK does not know, which fails closed.Ship a store build with a current SDK, and release without the type until then.
connection_metereddownloadStrategy is unmetered and the connection is metered or constrained.Wait for Wi-Fi, or set downloadStrategy to auto.
device_incompatibleThe release does not support this binary, OS or native fingerprint, and condition says which.Ship the store build, or widen the range: the fingerprint for fingerprint, the binary range for binary and os.
device_not_in_rolloutThe rollout has not reached this device yet.Raise the percentage, wait for the progression, or release to the one device: the rollout.
device_not_targetedThe release targets attributes or a device list this device does not match, and condition says which.Set the attributes before the first sync, or release without the condition. See Target devices with attributes.
release_older_than_binaryThe release was created before this binary was built, so the build excludes it.Create a release after the build.
release_revokedThe running release was revoked, and the device moves to an older eligible release or the embedded bundle.Publish a new release.
spending_cap_reachedThe organization's spending cap is reached and this device is beyond it this month.Raise the cap, or wait for the month to turn.

Failed reasons

A failure means the cycle could not finish, and every one retries on the next check.

ReasonMeansWhat to do
channel_unknownThe channel name set at runtime is not in the app's index of discoverable channels, or the build carries no channel, its build step having run offline or without a token, or the channel the device follows serves no index because it was deleted or has expired. The device keeps its bundle and its channel and keeps checking.Flag the channel discoverable or switch by id, or rebuild with a token. For a channel that is gone, clear a runtime choice with setChannel(null) as Return to the build's channel shows. A recreated channel gets a new id, so only a choice by name resolves again on its own.
content_mismatchedWhat was downloaded is not what the manifest promised: a file off its hash, a pack whose length is off its size, an entry past its size, a broken archive.A persistent one is a support request with the probe's --json.
device_offlineThe index could not be fetched and no usable cached copy exists.Do nothing, since the next check with a connection succeeds.
download_failedThe pack or a file could not be downloaded after three attempts inside the check, one and three seconds apart, or would not fit on the device. A 404 or 410 is not retried.Do nothing, since the next check tries again.
index_invalidThe index is in a format newer than this SDK knows, it failed to parse, or it names another app, channel or platform.Ship a store build with a current SDK. A persistent one on a current SDK is a support request.
manifest_invalidThe manifest breaks the wire rules, its bytes are off the hash the index promised, it names another bundle or platform, or a URL in it points outside HotCodePush.A persistent one is a support request with the probe's --json.
signature_invalidThe manifest's signature did not verify against the public keys the build lists.The release was signed with a key this build does not trust. See Sign your bundles.

device_offline, channel_unknown and index_invalid never leave the device as an event. The other four are reported as failed events and count in the release's download and verification failures.

Rollback reasons

A rollback is not a sync result: it arrives on the updateRolledBack event, on notifyReady()'s rollbackReason, and in the device's failed event for the release.

ReasonMeansWhat to do
app_crashedA start found the release's pending marker still set, so the previous run never reached readiness.The bundle crashes at start on this device, and auto-pause stops a release that does it on enough devices.
app_requestedThe app called rollbackUpdate(), with its own reason carried as the event's detail.What the app detected is in its reason text.
readiness_timed_outThe release did not signal readiness within readyTimeoutSeconds, 10 by default: no first render, or no notifyReady() under readySignal: manual.The bundle is broken on this device, or the app renders late. The release's counters say which, and Roll back a release covers the fleet.

After every rollback the device marks the bundle as failed on itself, which is what bundle_failed_before reports from then on.

What the device reports

A device reports each release it saw once, as event rows. A checked row carries available or skipped with the reason, and an applied row says the device started the release.

A confirmed row says the release passed the readiness gate, and a failed row carries its reason, a rollback among them. An up_to_date or a failed check reports nothing.

The console's device page and npx hotcodepush device get --device <id> list the rows, and npx hotcodepush release get prints the release's counters: applied, confirmed and failed by reason.

RowsMeans
checked available, applied, confirmedThe device took the release, started it and passed the readiness gate: the update landed.
checked available, applied, failed readiness_timed_out or app_crashedThe device started the release and rolled back, and the bundle is on its blocklist now.
checked available, nothing afterThe update is downloaded and waiting for its apply moment, still downloading, or the app holds restarts. The debug screen's Downloaded line settles it.
checked available, failed download_failed or signature_invalidThe download or its verification failed before any start, and the device retries on its next check.
checked skipped with a reason, nothing afterThe device evaluated the release and will not take it. The reason's row above says what to do.
no row at allThe device has not checked since the release went live, follows another channel, or can download updates but cannot report back.

A missing row is not evidence that the device did not update. A device that cannot report back updates normally, and the debug screen and the probe still work for it. The rows live as long as the release's bundle, the device's record 90 days after its last report. See Privacy and device data.

Last updated on

On this page