Tencent/WeKnora · error

get current user: %w

Error message

get current user: %w

What it means

Connector.ListResources calls GetCurrentUser (GET /api/v2/user) to identify whether the token is personal or a team token; any failure there is wrapped as "get current user: %w". Since virtually every subsequent step depends on knowing the user, this fails the whole listing. The wrapped cause can be transport errors, 401/403 ErrInvalidCredentials, 429, 4xx/5xx API errors, or JSON decode failures.

Source

Thrown at internal/datasource/connector/yuque/connector.go:70

// Serial fetch for v1 (user groups typically <10). TODO(perf): parallelize if slow.
func (c *Connector) ListResources(
	ctx context.Context, config *types.DataSourceConfig, parentID string,
) ([]types.Resource, error) {
	// Yuque resources are a flat list of repositories (no nesting), so a
	// lazy-load request for a specific parent has nothing extra to return.
	if parentID != "" {
		return []types.Resource{}, nil
	}

	cfg, err := parseYuqueConfig(config)
	if err != nil {
		return nil, err
	}
	cli := newClient(cfg)

	me, err := cli.GetCurrentUser(ctx)
	if err != nil {
		return nil, fmt.Errorf("get current user: %w", err)
	}

	repos := make(map[int64]v2Repo)

	// Team token: /api/v2/user returns type="Group" — the token represents a team,
	// not a personal user. In this case, directly list the team's own repos instead
	// of going through the personal-repos + user-groups flow.
	if me.Type == "Group" {
		logger.Infof(ctx, "[Yuque] detected team token (type=Group, login=%s), listing team repos directly", me.Login)
		teamRepos, err := cli.ListGroupRepos(ctx, me.Login)
		if err != nil {
			return nil, fmt.Errorf("list team repos: %w", err)
		}
		for _, r := range teamRepos {
			repos[r.ID] = r
		}
	} else {
		// Personal token flow: list user's own repos + repos from joined groups.

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Check errors.Is(err, datasource.ErrInvalidCredentials) first — if true, re-authorize: generate a fresh token in Yuque settings and update the datasource.
  2. For rate-limit messages, wait for the window to reset (Yuque allows roughly 100 req/5min on personal tokens) and reduce polling frequency.
  3. For timeouts/transport errors, verify egress connectivity from the deployment to the configured baseURL (DNS, proxy, firewall) and retry.
  4. For 5xx or decode errors, check the Yuque instance health/status page and retry; if persistent on self-hosted, upgrade or inspect the instance.
  5. Re-run the source's Validate to confirm credentials work before debugging ListResources further.

Example fix

resources, err := connector.ListResources(ctx, cfg, "")
if err != nil {
    if errors.Is(err, datasource.ErrInvalidCredentials) {
        return nil, fmt.Errorf("yuque token invalid, please reconnect the source: %w", err)
    }
    return nil, fmt.Errorf("listing yuque books failed (transient?): %w", err) // safe to retry
}
Defensive patterns

Strategy: retry

Validate before calling

// Go: ensure the datasource is valid before listing resources
if err := connector.Validate(ctx, cfg); err != nil {
    return nil, fmt.Errorf("fix credentials before listing resources: %w", err)
}

Type guard

// Go: check whether the current-user failure is credential-related
func isAuthError(err error) bool {
    return errors.Is(err, datasource.ErrInvalidCredentials)
}

Try / catch

var resources []types.Resource
err := retry.OnError(3, backoff.Exponential(2*time.Second), func() error {
    var e error
    resources, e = connector.ListResources(ctx, cfg, "")
    if e != nil && isAuthError(e) {
        return backoff.Permanent(e) // do not retry bad credentials
    }
    return e // retry transient failures
})
if err != nil {
    return fmt.Errorf("list yuque resources: %w", err)
}

Prevention

When it happens

Trigger: ListResources(ctx, config, "") invoked during resource browsing or sync when GET /api/v2/user fails: expired/revoked token (401), token lacking permission (403), network failure/timeout, rate limit exhausted after retries, or an unexpected 200 payload that fails to decode into v2UserResponse.

Common situations: Token invalidated after a password change or organization removal; a previously-valid token expired mid-session so browsing the source suddenly fails; rate limiting after heavy sync activity; transient network blips between the deployment and Yuque; self-hosted instance momentarily down.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/2c1b608b865b8971. Report an issue: GitHub.