Slack API · error code

Slack error user_not_found: Value(s) passed for users was invalid

Permanent - do not retryHTTP 200Channels, membership & DMs

Last verified against Slack API reference - chat.postMessage errors

What Slack returns
Value(s) passed for users was invalid.

What error user_not_found means

A user ID you passed does not resolve. On conversations.open — the method you call to start a DM or multi-person DM — the documented description is "Value(s) passed for users was invalid." As with channels, the near-universal cause is an identifier mixup: Slack user IDs look like U0123ABCDEF (or W... for some Enterprise Grid users), while @jane, display names, and email addresses are labels that this parameter does not accept.

The subtler causes are cross-boundary: a user ID harvested in workspace A used against workspace B (user IDs are workspace-scoped unless you are handling Grid-wide W IDs), an ID belonging to a deactivated account, or an ID that arrived from an external system with whitespace or truncation. For multi-person DMs, note the method's own bounds — its reference documents "Needs at least 2 users to open" (not_enough_users) and "Needs at most 8 users to open" (too_many_users) — and that you should not include the calling user's own ID in users.

To resolve a human to an ID reliably, use users.lookupByEmail (scope users:read.email) or capture the ID from events and interactive payloads, where Slack hands it to you directly. Once conversations.open succeeds, post to the returned channel.id, not to the user ID.

What it looks like

POST /api/conversations.open
{"users": "[email protected]"}

HTTP 200
{"ok": false, "error": "user_not_found"}

Why it happens

  • A display name, @handle, or email was passed where a U-prefixed user ID is required.
  • The ID belongs to a different workspace than the token (staging/production or multi-tenant mixups).
  • The account behind the ID was deactivated or deleted.
  • The ID was corrupted in storage or transit (truncation, whitespace, case damage).

How to fix Slack error user_not_found

  1. 1Log the exact users value sent and verify the U/W prefix and length.
  2. 2Resolve emails to IDs with users.lookupByEmail, or verify an ID with users.info from the same token.
  3. 3Check auth.test to confirm the token's workspace matches the ID's origin.
  4. 4For MPIMs, send 2-8 user IDs and exclude the calling user.
  5. 5After conversations.open succeeds, post to the returned channel.id rather than the user ID.

How to stop it recurring

Store Slack user IDs at the moment Slack gives them to you (event payloads, interaction payloads, users.lookupByEmail) and treat emails and handles as lookup keys, never as message targets. Re-validate stored IDs when sends start failing — deactivations are invisible until you check.

Official reference: Slack API reference - chat.postMessage errors. See all Slack error codes or the Slack limits and quotas.

Related codes

Error user_not_found - quick answers

What does Slack error user_not_found mean?

A user ID you passed does not resolve. On conversations.open — the method you call to start a DM or multi-person DM — the documented description is "Value(s) passed for users was invalid." As with channels, the near-universal cause is an identifier mixup: Slack user IDs look like U0123ABCDEF (or W...

How do I fix Slack error user_not_found?

1. Log the exact users value sent and verify the U/W prefix and length. 2. Resolve emails to IDs with users.lookupByEmail, or verify an ID with users.info from the same token. 3. Check auth.test to confirm the token's workspace matches the ID's origin. 4. For MPIMs, send 2-8 user IDs and exclude the calling user. 5. After conversations.open succeeds, post to the returned channel.id rather than the user ID.

Should I retry after error user_not_found?

No. Retrying the same request produces the same error; the condition has to be fixed first. Treat it as a permanent failure for that message and surface it, rather than looping.

Stop debugging Slack by hand

Connect the channel through Conferbot: tokens, webhooks and retries are handled, failures show as readable status.