Appearance
Errors
Every failure the Simulator can report is a typed error, and the tag of an error is the name of its class: error._tag and instanceof work on the same object, inside main and outside the call. A typed error is a condition your program can react to, because Instagram or the state of the world decided it, not a mistake in your code. A complete session is the one program that answers every error of a whole session; this page is the catalog: what each error means, what to do, and where to import its class.
Where an error reaches you
- Inside
main: answer it withcatchTag/catchTags. Every error thatmain's screens and actions can raise is handled there. There is nocatchAll: an error you do not answer stays in the type, andAndroidMainError<E>lets you check at compile time that none is left (the complete session ends with that check). - A challenge is not one of them. Instagram's
IgCheckpointErroris answered by theotherwisebranches you describe once, and the interrupted effect runs again.mainnever sees it and needs nocatchTag('IgCheckpointError')(Challenges: answer them once withotherwise). A lower-level effect that is not a screen action, called inmain, does keep it (Effects insidemain). - Outside
main: the call rejects with the same tagged object. Only what happens outsidemain's own work rejects the call, and all of it is in one documented union,AndroidIgpapiStartError(iOS:IosIgpapiStartError):- the stored value's decode errors (
SnapshotDecodeError,CheckpointDecodeError); - the checkpoint-versus-session refusals (
CheckpointWithSessionError,CheckpointWithoutSessionError); CheckpointScreenMismatchError, when a resume names a screen other than the checkpoint's;UnexpectedScreenError, when the app shows a screen neitherscreen:norotherwisedescribes;ChallengeStepNotModelledError, when a challenge asks for a step the Simulator cannot answer, and any error anotherwisebranch raises;- the start's own failure and the failure of the start-up's background requests (a session-fatal answer ends the process and rejects the call).
- the stored value's decode errors (
- To cancel, pass
signal(anAbortSignal) to any entry. Aborting interruptsmain, closes the process and rejects the call with the abort reason.
Defects are not errors
A defect is a mistake in your own program. No program can react to it, so it is not a typed error: it ends the call as a defect. The ones you can cause:
- an invalid option (a request timeout out of range, a protocol mode the platform does not have);
- an authenticator setup key that is not base32 (
totpCodeOfthrows aRangeError); - acting on a screen another screen covers, or on a handle that was closed or replaced:
ScreenNotOnTopError, whose message names the screen in focus. Close what covers the screen withback(), or continue with the handle the last call returned (Work with screens); - using a handle after
mainended. - a call that breaks an invariant the screens keep, named by its class so a
Causecan be told apart:PostingPhotoPickedInReelModeError(a photo picked in the Reel mode),PostingPostHasNoPhotoErrorandPostingCarouselPhotoMissingError(a post built with no photo, or with a photo the editor does not hold),SongTooShortForClipError(a song start that leaves less song than the clip lasts),RepostNoteEditorUnavailableError(the repost note editor is not part of this build),ScreenLaunchNotDeclaredErrorandLoginHomepageNotLaunchedError(a screen entered without its launch) andRecoverySearchClientInputParamsOrderError.
Import
The Import column says where a class is exported from, for an instanceof outside main. A class marked tag only is not exported: match it by its tag, error._tag === 'IgNotFoundError', or with Effect.catchTag inside main.
Retry or stop?
| Group | Do |
|---|---|
| The network and the answer | Retry later; report it if it repeats. |
| Your input (a wrong code, a weak password) | Fix the input and try again. |
| Limits and blocks | Back off or stop the account for a while; change the proxy; never retry in a loop. |
| The account (suspended, disabled) | Stop; only the account's owner can resolve it with Instagram. |
| The session is gone | Log in again with install. |
| A stored value cannot be read | Log in again, or fix the file. |
| The screens | Fix the order of your calls, or report it. |
What Instagram decided
These errors carry the response (error.response, error.body, error.text) and answer the question "what did Instagram say?".
| Tag | What it means | What to do | Import |
|---|---|---|---|
IgLoginBadPasswordError | The password is wrong. | Stop and ask for the right one. Retrying the same password only adds failed attempts. | tag only |
IgLoginInvalidUserError, IgLoginEmptyPasswordError | The username is not valid for Instagram, or the password is empty. | Fix the input; nothing to retry. | tag only |
IgLoginTwoFactorRequiredError | A request was answered with a demand for a code that no screen carries, or a wrong code was refused the same way. | Complete the two-factor screens (Log in). | tag only |
IgCheckpointError | Instagram raised a challenge. | Do nothing inside an entry: otherwise answers it. | tag only |
IgAccountSuspendedError, IgAccountDisabledError, IgInactiveUserError | Instagram suspended, disabled or deactivated the account. | Stop using the account. Only the account owner can resolve it with Instagram. | tag only |
IgPrivateUserError | The profile is private. | Read what you can see; the rest is not available to this account. | tag only |
IgLoginRequiredError, IgUserLoggedOutError | The session is gone. | Drop the stored checkpoint and log in again. | tag only |
IgCookieConsentRequiredError | Instagram asks for cookie consent; error.url is the consent page. | The account owner must accept it. | tag only |
IgSentryBlockError, IgIpBlockError | Instagram refused this device or this address. | Change the proxy, or slow down. Do not retry in a loop. | tag only |
IgSpamError | Instagram flagged the traffic as spam; error.expirationDate is the date of the block, when the answer names one. | Stop the action until that date. | tag only |
IgRateLimitError, IgBloks429Error | Instagram limited the traffic. | Back off; retry later, spread the actions out. | tag only |
IgNotFoundError | The resource does not exist, or no longer does. | Treat it as an absent user or media. | tag only |
RequestError | An error status the Simulator does not map to a specific error (a plain 400, 401, 403 or 5xx), or a body that is not JSON. It carries status, body and headers. | Retry a 5xx later; log the rest. | tag only |
IgChallengeNavigationVerifyCodeInvalidCodeError | A challenge's code was wrong. | Ask for another code and submit it (Codes that arrive during the run). | @igpapi/android |
IgChallengeNavigationSetNewPasswordTooEasyError | A challenge's new password is too easy. | Submit a stronger password. | @igpapi/android |
IgChallengeUnknownResponseError | A challenge answered with something the Simulator does not read. | Report it; the challenge stays open. | @igpapi/android |
ChallengeStepNotModelledError | A challenge asks for a step the Simulator cannot answer (surface names the kind, answer holds Instagram's answer). The challenge stays open and the next request is refused again. | Stop and let the account's owner pass the challenge. | @igpapi/android |
IgChallengeNavigationSubmitPhoneInvalidPhoneNumberError | A challenge's phone number is not one Instagram accepts. | Submit another number. | @igpapi/android |
UfacAuthenticityWizardMissingStateError, UfacAwaitingReviewMissingStateError | A verification step's answer lacks a value the step needs (field names it). | Report it; the challenge stays open. | @igpapi/android |
The network and the answer
| Tag | What it means | What to do | Import |
|---|---|---|---|
TransportError | The connection failed before an answer arrived (message, code, cause). | Retry; check the proxy. | tag only |
ParseError | The answer could not be read as JSON (body holds the text). | Retry; report it if it repeats. | tag only |
SchemaError, GraphqlRootFieldMissingError | The answer is not the shape the Simulator expects. | Report it with the request that failed. | tag only |
UsdidRegistrationRejectedError | The answer to a device-identity registration carried an error, so Instagram did not accept it. | Retry; the process may try again. | @igpapi/android |
IgExactUserNotFoundError | No account has exactly that username (the typed failure of UsersSearchExact). | Treat it as an absent user. | tag only |
MobileConfigAnswerDecodeError | The app's settings answer could not be read (detail says why); nothing of it is kept. | Retry; report it if it repeats. | tag only |
LicenseClaimMissingError | The licence token lacks a claim the packages require. | Get a valid token (Get access and install). | tag only |
The screens
| Tag | What it means | What to do | Import |
|---|---|---|---|
ScreenEnterConcurrentError | You started a second screen transition while another one was still running. | Run transitions one after another. | tag only |
ScreenEdgeInputError | The next screen refused the input of the edge you took. | Fix the input. | tag only |
ScreenDataError | Instagram's answer no longer matches what the screen declares (detail names the field). | Report it; the screen is rolled back and the old handle stays on top. | tag only |
ScreenTrailAmbiguousItemError | A checkpoint cannot be taken, because an item's key is not unique in its list. | Report it. | tag only |
UnexpectedScreenError | The app shows a screen that neither screen: nor an otherwise branch describes (expected, found). | Add the branch, or name the screen you mean. | @igpapi/android |
CarouselSlideNotFoundError | The slide you named is not one of the post's. | Use an index below the post's slide count. | @igpapi/android |
CarouselSlidesNotLoadedError | The post's slides are not loaded, so the slide cannot be named. The slide may exist. | Open the post again, then swipe. | @igpapi/android |
ChallengeWithoutProcessError | OpenChallenge was given a challenge that was not raised in an app process of the Simulator. Nothing was sent. | Use otherwise, or open the challenge in the process that raised it. | @igpapi/android |
FbidV2UnknownError | Your own profile cannot open: the session holds no Facebook id of the viewer yet, because neither a login answer nor a launch has taught it. | Log in again, then launch from that session. | @igpapi/android |
The stored session
| Tag | What it means | What to do | Import |
|---|---|---|---|
SnapshotDecodeError | A stored snapshot or checkpoint cannot be restored: damaged, a string instead of an object, a newer or foreign format, or written for another app profile. | Log in again with install (Keep a session). | @igpapi/android |
CheckpointDecodeError | A checkpoint's open screens are damaged, or the checkpoint is from a release before 4.11.0. | Log in again (Keep a session). | @igpapi/android |
CheckpointWithSessionError, CheckpointWithoutSessionError | A checkpoint's screen and its session disagree: a signed-in screen without a session, or a screen before sign-in with one. Nothing was sent. | Start from a checkpoint that belongs together. | @igpapi/android |
CheckpointScreenMismatchError | A resume names a screen other than the checkpoint's. Nothing was sent. | Name the checkpoint's screen, or drop screen. | tag only |
FeedCheckpointDecodeError | A feed's stored cursor is not an object (text included). | Parse the stored text and pass the object (Lists). | tag only |
ScreenTrailFormatError | A stored trail of screens is in a format this release does not read. | Log in again. | tag only |
AppAlreadyStartedError | A second launch inside one app layer; the process was already launched by an earlier login. | Launch once per layer. | tag only |
WarmLaunchProfileError | A stored session carries an app profile that is not the current build, so the launch has no order it can follow. | Log in again with install. | @igpapi/android |
ScreenTrailDecodeError | A step of a stored trail does not decode: an unknown screen, the root's input or an edge's arguments. | Log in again. | tag only |
ScreenTrailMismatchError | A stored trail belongs to another account, phone, platform or root. Nothing was sent. | Use the trail with the account it was taken on, or log in again. | tag only |
ScreenTrailUnsupportedError | The trail's screen on top is not one that retrace can walk again. Nothing was sent. | Log in again, or start from a checkpoint. | tag only |
ScreenTrailInsideEnterError | A trail was asked for while a screen was still opening. | Ask for it after the screen opened. | tag only |
ScreenRetraceError | A retrace could not take a step again over fresh data (the screen has no such edge, or the edge now leads to another screen). | Log in again, or start from a checkpoint. | tag only |
ScreenRetraceItemMissingError | A retrace looked for the item an edge was taken from, and it is no longer in the fresh data. | Start from a checkpoint. | tag only |
ScreenRetraceStepError | A retrace opened a screen again and its fresh enter failed (cause is that error). | Answer cause; retry later. | tag only |
Log in and two-factor
| Tag | What it means | What to do | Import |
|---|---|---|---|
LoginBloksRejectedError | Instagram rejected the login with an answer the Simulator does not recognise. | Stop; report it if the password is right. | @igpapi/android |
LoginAccountRecoveryRequiredError, LoginLastResortRecoveryRequiredError | The login escalated to account recovery (a code by email) instead of a session. | Recover the account (Account recovery). | @igpapi/android |
LoginAccountRecoveryContinueError | The recovery dialog could not continue. | Stop; report it. | @igpapi/android |
LoginBloksParseError | The login answer, or the screen behind it, could not be read (bodyExcerpt says what was sent). | Retry; report it if it repeats. | @igpapi/android |
PasswordEncryptionKeysUnavailableError | The session holds no password-encryption key, so the password cannot be sent. | Start from a fresh install. | @igpapi/android |
LoginTwoFactorApprovalDeclinedError | The login was declined on the other device. | Stop. | @igpapi/android |
LoginTwoFactorAuthenticationAppCodeRejectedError | The authenticator code was rejected. | Compute the code again at the submit; check the setup key. | @igpapi/android |
LoginTwoFactorEntrypointParseError | The second-step answer was empty or unreadable. | Retry; report it if it repeats. | @igpapi/android |
TwoFactorBloksIssuedIdMissingError, TwoFactorBloksLoginResponseNotFoundError | A value the second step must carry is missing, or the answer to the code carries no login. | Start the login again. | @igpapi/android |
TwoFactorBloksInvalidCodeError | The code was wrong, expired, or refused for too many attempts. | Ask for the code again. | @igpapi/android |
AccountRecoveryBloksIssuedParamsMissingError | A value the recovery must carry is missing. | Start the recovery again. | @igpapi/android |
AccountRecoveryBloksInvalidCodeError | The emailed recovery code was wrong. | Ask for another code with requestNewCode(). | @igpapi/android |
LoginTwoFactorRequiredError | The account asks for a second step. Over the app layer, AndroidLogin fails with it. | Finish it with the effects of Two-factor without the screens; the screens answer it with a screen instead. | @igpapi/android |
PcdStateError | The pre-login screen's answer cannot be read, or an id the next request must echo is empty. | Start again from a fresh install; report it if it repeats. | @igpapi/android |
TwoFactorTicketUnknownError | A two-factor ticket the process does not know: issued elsewhere, or corrupt. | Start the login again. | @igpapi/android |
AccountRecoveryBloksUnknownResponseError | The recovery code was answered with neither an accepted login nor a rejection. | Retry; report it if it repeats. | @igpapi/android |
Registration
| Tag | What it means | What to do | Import |
|---|---|---|---|
RegistrationInvalidPhoneError | The number is not one Instagram accepts for a new account. | Fix the number. | @igpapi/android |
RegistrationSmsCodeError | The SMS code is wrong, expired or too short. | Read the code again (Codes that arrive during the run). | @igpapi/android |
RegistrationWeakPasswordError | The password is too short or too weak. | Choose another. | @igpapi/android |
RegistrationInvalidBirthdayError | The birthday is invalid, or the person is under 18. | Fix the date. | @igpapi/android |
RegistrationInvalidNameError | The full name is too long or not accepted. | Choose another. | @igpapi/android |
RegistrationUsernameTakenError | The username is taken or not allowed. | Choose another. | @igpapi/android |
RegistrationCreateAccountError | Instagram refused to create the account. | Stop; try later with another number. | @igpapi/android |
RegistrationSpamError | Instagram flagged the sign-up as spam and stopped the flow. | Stop; change the proxy and wait. | @igpapi/android |
RegistrationChallengeRequiredError | A step's answer asked for an account-verification challenge before continuing. | Answer it with otherwise (Create an account). | @igpapi/android |
RegistrationStateMissingError | The request cannot be built: an earlier step's answer was never accepted in this process. | Walk the steps in order in one process. | @igpapi/android |
RegisteredButLaunchFailedError | The account exists, but the launch after it failed. The terms screen is still on top. | Call its retryLaunch(); never register again. | @igpapi/android |
Reposts, Direct and publishing
| Tag | What it means | What to do | Import |
|---|---|---|---|
MediaRepostTextTooLongError | The repost text is too long. | Shorten it. | @igpapi/android |
MediaRepostTextNotAcceptedError | This build takes no text with a repost. | Repost without text. | @igpapi/android |
MediaRepostCarouselIndexError | The post holds no carousel slide at that index. | Use an index the post has. | @igpapi/android |
DirectThreadNotFoundByParticipantsError | Instagram named no conversation for the people you picked. | Pick the people again. | @igpapi/android |
DirectGroupNameUnavailableError | The group name editor belongs to group conversations; a one-to-one conversation does not open it. | Use it on a group. | @igpapi/android |
PostingMediaFormatError | The file is neither a photo nor a video the picker offers, or it carries a mark the app refuses (a content-credentials manifest, an IPTC record or a generated-media source type). | Offer another file (Publishing). | @igpapi/android |
PostingPhotoEncodeError, PostingVideoEncodeError | The photo or the video cannot be encoded for upload; the reason says why. | Offer another file. | @igpapi/android |
PostingMediaNotInProcessError | The publication continues in a process that does not hold the file it picked (a checkpoint carries no files). | Pick the file again. | @igpapi/android |
PostingSongNotInProcessError | The Reel's song was downloaded by another process. | Pick the song again. | @igpapi/android |
PostingCreationModeNotRecordedError | The move between creation modes you asked for is not one the app offers. | Open the mode directly with openCreation(mode). | @igpapi/android |
PostingStoryNotPublishedError | The story was created, but Instagram's status for it is not completed. It carries the story and the status. | Show the status; check the story on the account. | @igpapi/android |
ReelAudioMixError, ReelSongDownloadError | The Reel's sound cannot be mixed, or the song cannot be fetched. | Offer another file or another song, or try again. | @igpapi/android |
MediaRepostMediaNotFoundError | Instagram's answer for the post carried no usable item. | Treat the post as absent. | @igpapi/android |
DirectInboxSeqIdUnknownError | The participant lookup of "New message" needs the inbox's sequence number, which no inbox answer has taught the session yet. | Open the inbox first, then "New message". | @igpapi/android |
MessengerMediaUploadHttpError | The upload slot or the file's POST answered a status that is not 2xx (status). | Retry later; offer another file. | tag only |
MessengerMediaUploadMalformedError | The upload answered 2xx but carried no media id. | Retry; report it if it repeats. | tag only |
Telemetry
FlushTelemetry fails with TelemetryDeliveryError: the channel's events are put back unchanged, so running it again sends the same events. TelemetryDeliveryError is the union of the two failures below, and TelemetryDeliverySessionError is the third. See Telemetry.