multica-ai/multica · error · ErrTokenAppMismatch

slack: the bot token and app-level token are from different

Error message

slack: the bot token and app-level token are from different Slack apps

What it means

Slack BYO validation error: the pasted xoxb- bot token and xapp- app-level token belong to DIFFERENT Slack apps. Persisting such a pair would appear connected but be broken: inbound events arrive over the app token's Socket Mode connection (routed by its app id) while mention detection and outbound posting use the bot token's identity.

Source

Thrown at server/internal/integrations/slack/byo_install.go:29

	"github.com/jackc/pgx/v5/pgtype"
	"github.com/slack-go/slack"

	db "github.com/multica-ai/multica/server/pkg/db/generated"
)

// ErrInvalidBotToken / ErrInvalidAppToken are returned by RegisterBYO when a
// pasted token is malformed (wrong prefix, or an app token whose app id cannot
// be parsed). The handler maps them to 400 so the dialog can show a precise hint
// instead of a generic failure.
var (
	ErrInvalidBotToken = errors.New("slack: bot token must start with xoxb-")
	ErrInvalidAppToken = errors.New("slack: app-level token must start with xapp- and embed an app id")
	// ErrTokenAppMismatch is returned when the pasted bot token and app-level
	// token belong to DIFFERENT Slack apps. Persisting that pair would "connect"
	// but be broken: inbound arrives on the app token's socket (routed by its
	// app id) while mention detection + outbound use the bot token's identity.
	ErrTokenAppMismatch = errors.New("slack: the bot token and app-level token are from different Slack apps")
)

// RegisterBYOParams are the inputs for a bring-your-own-app install: the agent
// this bot represents, who is installing, and the two tokens the user pasted
// from their own Slack app.
type RegisterBYOParams struct {
	WorkspaceID pgtype.UUID
	AgentID     pgtype.UUID
	InitiatorID pgtype.UUID
	BotToken    string // xoxb-… — outbound Web API (chat.postMessage)
	AppToken    string // xapp-… — this app's OWN Socket Mode connection (inbound)
}

// RegisterBYO installs a user-supplied ("bring your own") Slack app for an agent.
// The user creates their own Slack app, installs it to their workspace, and
// pastes its bot token (xoxb-) + app-level token (xapp-). There is NO OAuth code
// exchange: we validate the bot token live via auth.test (which also yields the
// team id + bot user id), prove the bot + app tokens belong to the SAME app,

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. Open ONE Slack app's configuration and copy both tokens from that same app: Bot User OAuth Token (xoxb-) from OAuth & Permissions and App-Level Token (xapp-) from Basic Information.
  2. Delete the stale/duplicate app if it exists, so only one candidate remains to copy from.
  3. After re-copying, re-run RegisterBYO; the mismatch check passes only when both tokens embed the same app id.

Example fix

// before
params.BotToken = "xoxb-..." // app A
params.AppToken = "xapp-..." // app B
err := svc.RegisterBYO(ctx, params)
// -> "slack: the bot token and app-level token are from different Slack apps"

// after: pre-validate app id alignment in the handler
botAppID, appAppID := parseAppID(params.BotToken), parseAppID(params.AppToken)
if botAppID != "" && appAppID != "" && botAppID != appAppID {
	return respondError(w, 400, "both tokens must come from the same Slack app")
}
err := svc.RegisterBYO(ctx, params)
Defensive patterns

Strategy: validation

Validate before calling

botApp := appIDFromToken(params.BotToken)  // parses app id from xoxb- token
appApp := appIDFromToken(params.AppToken) // parses app id from xapp- token
if botApp != "" && appApp != "" && botApp != appApp {
	return respondError(w, 400, "both tokens must come from the same Slack app")
}
_ = svc.RegisterBYO(ctx, params)

Try / catch

if err := svc.RegisterBYO(ctx, params); err != nil {
	if errors.Is(err, slack.ErrTokenAppMismatch) {
		return respondError(w, 400, "bot token and app token are from different apps — copy both from ONE app")
	}
	return err
}

Prevention

When it happens

Trigger: Calling RegisterBYO where the app id embedded in the xapp- token does not match the app id of the xoxb- bot token — e.g. the admin created two Slack apps and copied the bot token from one and the app-level token from the other.

Common situations: Two similarly named apps in the Slack dashboard; regenerated tokens in a new app after following an outdated tutorial; copy/paste mix-up between browser tabs each open to a different app's credentials page.

Related errors


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/77ce86efeb928154. Report an issue: GitHub.