The short answer
If Whizi rejected your import, check the file you picked first: the only file Whizi reads is conversations.json inside a ChatGPT or Claude export, so unzip the export and pick that file rather than the zip itself. Past that, an import fails in one of two places and the wording of the message tells you which: the browser parser that reads your export file, or the import endpoint that receives the conversations the parser produced. File errors are about the file you picked. Upload errors are about the network or the session. Nothing in between is ambiguous, because each message is a fixed string tied to one condition.
The second thing to know before you retry anything: re-running an import never duplicates chats. Every imported conversation is keyed by account, source, and source id, so importing the same export twice, resuming after a dropped connection, or clicking Import twice all land the same chats once.
| What you saw | Where it failed | What to do |
|---|---|---|
| A message about the export format or conversations.json | Reading your file, before anything uploaded | Pick a different file out of the export, see the table below |
| A message about your session or your connection | Uploading, part way through | Sign in again or reconnect, then run the import again |
| A count of conversations that could not be imported | Some batches failed every retry | Run the import again, it picks up only what is missing |
| Nothing, but it is taking a long time | Rate limiting, working as designed | Wait, the importer retries on its own |
Errors from reading your export file
These come from the browser, before a single byte leaves your machine. The export file itself is never uploaded: the browser parses it and posts only normalized conversations, so an error here means the file never got far enough to be sent.
| Message | Trigger | Fix |
|---|---|---|
That file is not a ChatGPT or Claude export. Look for conversations.json inside the export zip. | The parser cannot identify either export format, or a zip yields an unrecognized payload | Open the export archive and pick conversations.json specifically |
There is no conversations.json inside that zip. Unzip it and pick the file directly. | The zip you picked has no matching entry | Unzip it yourself, find conversations.json, and pick that file |
That file is not valid JSON, so there was nothing to read. | The picked file fails to parse as JSON | Download the export again from ChatGPT or Claude and pick conversations.json from it |
That export has no conversations with text in them. | The export parses but yields zero conversations | The export is genuinely empty of text transcripts. Nothing to fix on the Whizi side |
That file is too large for the browser to open. Pick the export .zip instead, which is read one file at a time. | The picked raw .json file is over the browser read cap | Pick the .zip instead. A raw .json export is accepted up to 300 MB; the .zip path has no ceiling of its own, because only the conversations.json entry is decompressed |
Could not read that file. Please try again. | File reading threw for any other reason | Genuinely a retry case. If it repeats on the same file, pick the export .zip, which is read one entry at a time |
The first message is the broad one, because one string covers two conditions: an export format the parser cannot identify, and a zip that yields an unrecognized payload. Both land on the same fix, which is to unzip the export and pick conversations.json directly.
Errors from the upload itself
Once the file parses, the importer posts the conversations in batches. Two things can go wrong at that stage, and both are recoverable.
| Message | Trigger | Fix |
|---|---|---|
Your session ended. Sign in again, then start the import. | The token fetch returned nothing part way through the import | Sign in again, then start the import over. Whatever already landed stays, and the re-run skips it |
The import could not be finished. Check your connection and try again. | Any other upload failure during the import run | Check the connection and run it again |
A third outcome is not an error at all but a summary: {count} could not be imported. Run the import again to pick them up. That is the count of conversations whose batches failed every retry. The instruction in the message is the whole fix, and the dedupe key described in the short answer is why the second run costs you nothing.
Errors the import endpoint returns
These are the codes and strings the import route itself produces. The website mirrors the same caps and validates before posting, so they matter most when something is posting to the endpoint directly or when a batch is malformed.
| Code | Message | Trigger |
|---|---|---|
invalid_import | A JSON object body is required. | The import body is not an object |
invalid_source | An import source of chatgpt or claude is required. | The source field is missing or is not one of the two accepted sources |
empty_import | At least one conversation is required. | The conversations array is missing or empty |
too_many_conversations | This batch has {count} conversations, over the 25 per request limit. | More than 25 conversations in one request |
too_many_messages | Conversation {n} carries {count} messages, over the 400 per request limit. Send the rest as an append. | More than 400 messages in one conversation in one request |
invalid_import | Conversation {n} is not an object. | A conversations array entry is not an object |
invalid_import | Conversation {n} has no messages array. | A conversation carries no messages array |
invalid_import | Conversation {n} has an invalid append target. | The appendTo field is neither a string nor null |
invalid_message | Conversation {n} message {m} is not an object. | A message entry is not an object |
invalid_message | Conversation {n} message {m} needs a role of "user" or "assistant". | A message has a role outside those two |
invalid_message | Conversation {n} message {m} has no text. | The message content is not a string |
request_too_large | Request is too large. | The JSON body exceeds the route byte cap, either by declared Content-Length or by bytes actually read |
The caps behind those messages: 25 conversations per request, 400 messages per conversation per request, and a request body of at most 2,000,000 bytes. The website importer splits at exactly 25 and 400 and holds each request under 1,200,000 bytes, deliberately below the 2,000,000 byte cap to leave room for the request envelope. A conversation longer than 400 messages is not rejected, it is sliced: the remainder is sent as append slices onto the chat the first slice created.
A large import pauses for 20 seconds at a time
Importing conversations is rate limited to 20 requests per minute per user. A large export will hit that ceiling, and that is expected rather than broken.
You will not see an error when it happens. An import that hits HTTP 429 is not surfaced: the client waits 20 seconds and retries, up to 4 attempts per batch. So an import that looks stalled for twenty seconds at a time on a big export is doing exactly what it should. Leave it running.
If batches still fail after those 4 attempts, they land in the {count} could not be imported. Run the import again to pick them up. summary, and running the import a second time is the fix rather than support.
What the import drops on purpose
Some content is dropped by design, and an import that succeeds can still look incomplete next to the original.
For a ChatGPT export, only the branch that was on screen is imported. Regenerated replies and discarded drafts are not replayed as messages. Non-transcript content is skipped too: hidden reasoning, analysis-tool code and output, browsing scratchpads, custom-instruction blocks, and function calls.
For a Claude export, thinking blocks, tool calls, and attachments are dropped. Only text blocks are imported.
Conversations in the file holding no readable text are counted and reported as skipped rather than silently dropped, so a skipped count is information, not a failure.
A conversation with no usable title becomes Imported chat, and a title longer than 120 characters is trimmed. An imported message longer than the content cap is truncated rather than rejected, so one oversized message does not cost you the rest of that conversation.
Finally, timestamps: an imported message dated before 2015-01-01, or dated in the future, is discarded as a timestamp and the row falls back to the import time. A chat that lands with the date you ran the import, instead of its original date, hit that rule.
Why running the import again is safe
The dedupe key in the short answer has a fallback. When an export gives no stable conversation id, the key becomes a hash of the transcript itself, so a re-run still matches those conversations rather than adding second copies.
One consequence to know about: deleting an imported chat and then importing the same export again brings the chat back rather than reporting a duplicate. If you deliberately deleted an imported conversation, do not re-run that export unless you want it returned.
- Pick conversations.json out of the export, not the export zip itself
- A raw .json export is accepted up to 300 MB, past which use the .zip
- Session and connection errors mean sign in or reconnect, then re-run
- A count that could not be imported means run the import again
- After any import error, run the same import again before anything else
- Deleting an imported chat and re-importing brings it back
- A large import pausing for 20 seconds at a time is rate limiting, not a fault
- ChatGPT regenerated branches, and Claude thinking blocks and attachments, are dropped by design
Frequently asked questions
Whizi says my ChatGPT export is not a ChatGPT export. Why?
The message is That file is not a ChatGPT or Claude export. Look for conversations.json inside the export zip. and it fires when the parser cannot identify either format in the file you picked, or when a zip yields an unrecognized payload. The file Whizi reads is conversations.json, so unzip the export and pick that file directly. If you picked the zip and got There is no conversations.json inside that zip. Unzip it and pick the file directly. instead, the zip has no matching entry at all and the export needs downloading again.
My import stopped part way through. Will running it again duplicate my chats?
No. Re-running is the intended recovery for a dropped connection, an ended session, or a failed batch: the second run lands the same chats once and picks up only what is missing. There is no cleanup step to do first.
Why did only some of my conversations import?
Two different counts can appear, and only one of them is a failure. {count} could not be imported. Run the import again to pick them up. counts batches that failed every retry, and re-running the import is the fix. A skipped count is the other one, and it reports conversations in the file that hold no readable text rather than conversations that went wrong.
The import has been sitting there for a while. Is it broken?
Watch whether it moves again rather than how long it has been going. A pause of roughly 20 seconds followed by more progress is the rate limiter, because the client waits 20 seconds and retries instead of showing you anything. An import that is actually finished says so, either with one of the error strings on this page or with the {count} could not be imported. Run the import again to pick them up. summary. Silence plus periodic progress means leave it alone.
Does my ChatGPT or Claude export file get uploaded to Whizi?
No. The export file itself never reaches the server. Your browser reads it, parses it, and posts only the normalized conversations, which is also why every format error on this page happens before anything is sent. The full data handling detail is in what Whizi does with your data.