Skip to content

[BUG] DELETE /instance/logout/{name} returns HTTP 500 (PrismaClientKnownRequestError on messageUpdate.create) despite Baileys session closing successfully #2567

@irlanviana

Description

@irlanviana

Welcome!

  • Yes, I have searched for similar issues on GitHub and found none.

What did you do?

  1. Connect a WhatsApp Baileys instance and let it accumulate some message history (the bug appears to need _count.Message > 0).

  2. Call DELETE /instance/logout/{instanceName} with a valid apikey header:

    curl -X DELETE -H "apikey: $KEY" "$EVOLUTION_API_URL/instance/logout/suporte"

What did you expect?

HTTP 200 with the documented logout success body:

{"status": "SUCCESS", "error": false, "response": {"message": "Instance logged out"}}

What did you observe instead of what you expected?

HTTP 500 with a PrismaClientKnownRequestError on messageUpdate.create() in the post-logout cleanup path. The Baileys session does close — the next connectionState call returns state: "close" — but the HTTP-level error makes downstream clients believe the operation failed.

Full response body:

{
  "status": 500,
  "error": "Internal Server Error",
  "response": {
    "message": [
      "PrismaClientKnownRequestError: \nInvalid `this.prismaRepository.messageUpdate.create()` invocation in\n/evolution/dist/main.js:250:5832\n\n  247   WHERE \"instanceId\" = ${this.instanceId}\n  248   AND \"key\"->>'id' = ${S}\n  249   LIMIT 1\n→ 250 `)[0]||null,!m?.id){this.logger.warn(`Original message not found for update. Skipping. Key: ${JSON.stringify(i)}`);continue}u.messageId=m.id}if(n.message===null&&n.status===void 0){this.sendDataWebhook(\"messages.delete\",{...i,status:\"DELETED\"}),this.configService.get(\"DATABASE\").SAVE_DATA.MESSAGE_UPDATE&&await this.prismaRepository.messageUpdate.create(\nAn operation failed because it depends on one or more records that were required but not found. No record was found for a delete."
    ]
  }
}

Immediately after the 500, connectionState confirms the logout actually happened:

{"instance":{"instanceName":"suporte","state":"close"}}

Also worth noting: connectionStatus in fetchInstances does not flip from "open" even after this — it stays "open" indefinitely while disconnectionReasonCode and disconnectionAt are populated. So clients relying on connectionStatus (or anything that reads through it) end up with stale state.

Screenshots/Videos

No response

Which version of the API are you using?

evoapicloud/evolution-api:v2.3.7 (Docker, latest stable tag as of 2026-05-26)

What is your environment?

Docker

Other environment specifications

  • Image: evoapicloud/evolution-api:v2.3.7 (Docker)
  • Hosting: Linux container (EasyPanel)
  • Integration: WHATSAPP-BAILEYS
  • DATABASE_SAVE_DATA_MESSAGE_UPDATE: enabled (default)
  • Database: Postgres via Prisma

If applicable, paste the log output

PrismaClientKnownRequestError:
Invalid `this.prismaRepository.messageUpdate.create()` invocation in
/evolution/dist/main.js:250:5832

  247   WHERE "instanceId" = ${this.instanceId}
  248   AND "key"->>'id' = ${S}
  249   LIMIT 1
→ 250 `)[0]||null,!m?.id){...await this.prismaRepository.messageUpdate.create(...)

An operation failed because it depends on one or more records that were required but not found. No record was found for a delete.

Additional Notes

Workaround we adopted (TypeScript client):

try {
  return await evolutionFetch(`/instance/logout/${name}`, { method: "DELETE" });
} catch (err) {
  const state = await getInstanceStatus(name).catch(() => null);
  if (state?.instance?.state && state.instance.state !== "open") {
    return { status: "SUCCESS", recoveredFrom: "evolution-500" };
  }
  throw err;
}

Related issues (same code path, different symptoms; both closed as "not planned"):

These three issues seem to share the same root cause: messageUpdate.create() in whatsapp.baileys.service.ts doesn't defensively handle all the edge cases that can legitimately fire it (message edits with no parent, logout-time cleanup, undefined remoteJid, etc.). Suggestions:

  1. Guard the messageUpdate.create() call with the same !m?.id check that the surrounding logger.warn already uses.
  2. At minimum, don't propagate the cleanup error as an HTTP 500 — the logout succeeded; the response should reflect that. Wrapping the messageUpdate.create() block in its own try/catch would prevent the secondary failure from masking the primary success.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions