bytebase/bytebase · error

failed to get token

Error message

failed to get token

What it means

refreshToken wraps any error from getTokenCached (the DingTalk token endpoint or its cache path) with "failed to get token". The DingTalk provider needs an access token before calling any API; if obtaining/caching that token fails, this wrapper is raised. It indicates the provider cannot authenticate to DingTalk at all, so all downstream calls fail.

Source

Thrown at backend/plugin/webhook/dingtalk/app.go:57

	}
	mobile, err := getDingTalkMobileFromPhone(phone)
	if err != nil {
		return errors.Wrapf(err, "failed to parse phone number")
	}
	id, err = p.getIDByPhone(ctx, mobile)
	if err != nil {
		return errors.Wrapf(err, "failed to get user id by phone")
	}
	if err := p.sendMessage(ctx, []string{id}, "test", "test"); err != nil {
		return errors.Wrapf(err, "failed to send test message")
	}
	return nil
}

func (p *provider) refreshToken(ctx context.Context) error {
	token, err := getTokenCached(ctx, p.c, p.id, p.secret)
	if err != nil {
		return errors.Wrapf(err, "failed to get token")
	}
	p.token = token
	return nil
}

var userIDCache = func() *lru.Cache[string, string] {
	cache, err := lru.New[string, string](5000)
	if err != nil {
		panic(err)
	}
	return cache
}()

// https://open.dingtalk.com/document/orgapp/query-users-by-phone-number
func (p *provider) getIDByPhone(ctx context.Context, phone string) (string, error) {
	if id, ok := userIDCache.Get(phone); ok {
		return id, nil
	}

View on GitHub (pinned to 1870550677)

Solutions

  1. Verify the DingTalk appKey (id) and appSecret configured on the webhook provider are correct and the app is enabled
  2. Check network egress to https://oapi.dingtalk.com and https://api.dingtalk.com from the server
  3. Inspect the wrapped cause (err chain) for the exact DingTalk errcode and fix accordingly
  4. Retry after confirming DingTalk service status if it was transient

Example fix

// before
provider := dingtalk.New(ctx, httpClient, "", "wrong-secret")
// after
provider := dingtalk.New(ctx, httpClient, "ding-app-key", "correct-app-secret")
Defensive patterns

Strategy: try-catch

Validate before calling

if provider.ID == "" || provider.Secret == "" {
	return errors.New("dingtalk appKey/appSecret must be set before validating webhook")
}

Try / catch

if err := p.refreshToken(ctx); err != nil {
	var dingErr *errors.Error
	if errors.As(err, &dingErr) {
		log.Printf("dingtalk token error: %v", dingErr)
	}
	return fmt.Errorf("webhook validation aborted: token unavailable: %w", err)
}

Prevention

When it happens

Trigger: Calling Validate, do, or posting a webhook issue when getTokenCached fails: wrong appKey/appSecret (p.id/p.secret), DingTalk token endpoint unreachable, or the cached-token fetch returning an API error.

Common situations: Misconfigured DingTalk app credentials in webhook settings; rotated/revoked app secret; corporate firewall blocking oapi.dingtalk.com / api.dingtalk.com; DingTalk-side outage or rate limiting of the token endpoint.

Related errors


AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06). Data as JSON: /api/errors/128e46dda5a86a4d. Report an issue: GitHub.