chenhg5/cc-connect · error

%s: resource download auth: %w

Error message

%s: resource download auth: %w

What it means

This error wraps any failure to obtain the tenant access token needed to authenticate a Feishu message-resource download. downloadResourceChunked calls fetchResourceTokenOrDefault (which mints a fresh tenant_access_token via the Lark SDK) before any HTTP download; if that fails, the error is wrapped with the platform tag and 'resource download auth' context. The underlying cause (network, bad app credentials, Feishu API error) is in the wrapped error.

Source

Thrown at platform/feishu/resource_download.go:96

	}
	if p.resourceDownloadHTTP == nil {
		// Defensive: callers running outside the normal constructor (notably
		// unit tests that synthesise a Platform value) still get a sane
		// client. We log instead of panicking so one stale test fixture
		// doesn't crash the whole process.
		slog.Warn(p.tag() + ": resourceDownloadHTTP is nil; using default client")
		p.resourceDownloadHTTP = &http.Client{Timeout: 60 * time.Second}
	}
	if p.resourceChunkSize <= 0 {
		p.resourceChunkSize = defaultResourceChunkSize()
	}
	if p.resourceMaxBytes <= 0 {
		p.resourceMaxBytes = defaultResourceMaxBytes
	}

	token, err := p.fetchResourceTokenOrDefault(ctx)
	if err != nil {
		return nil, fmt.Errorf("%s: resource download auth: %w", p.tag(), err)
	}

	return p.resourceDownloadStream(ctx, token, messageID, fileKey, resType)
}

// resourceDownloadStream executes the actual download. Split out so the
// helper's preflight (validation, token, defaults) stays readable.
func (p *Platform) resourceDownloadStream(ctx context.Context, token, messageID, fileKey, resType string) ([]byte, error) {
	probeCtx, cancel := context.WithTimeout(ctx, resourceRangeProbeTimeout)
	defer cancel()

	first, total, err := p.resourceFetchFirstChunk(probeCtx, token, messageID, fileKey, resType)
	if err != nil {
		// Fallback: try a single plain GET. Some servers reject Range entirely
		// with 4xx instead of silently ignoring it.
		slog.Warn(p.tag()+": first-chunk fetch failed; trying plain GET",
			"error", err, "file_key", fileKey, "type", resType)
		return p.resourceSingleGet(ctx, token, messageID, fileKey, resType)

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check app_id/app_secret in config.toml and verify the app is enabled with im:resource permissions
  2. Read the wrapped error (%w) for the real cause; if it is 99991663/99991661 the token/secret is wrong
  3. Verify network connectivity to the Feishu (or Lark) API domain configured for the platform
  4. Retry after a rate-limit backoff if the cause is token-endpoint throttling

Example fix

// before: hard to tell which credential failed
secret := os.Getenv("FEISHU_SECRET")
// after: fail fast with validation at startup
if os.Getenv("FEISHU_SECRET") == "" { log.Fatal("FEISHU_SECRET not set") }
Defensive patterns

Strategy: try-catch

Validate before calling

if appID == "" || appSecret == "" { return errors.New("feishu app_id/app_secret not configured") }

Type guard

var authErr *AuthError; if errors.As(err, &authErr) { /* handle token failure */ }

Try / catch

data, err := agent.DownloadResource(ctx, msgID, fileKey, "image")
if err != nil && strings.Contains(err.Error(), "resource download auth") {
    slog.Error("feishu token failure; check app credentials", "err", err)
    return
}

Prevention

When it happens

Trigger: Downloading an image or file from a Feishu message when fetchFreshTenantAccessToken fails: invalid app_id/app_secret, expired or revoked credentials, no network access to Feishu's auth endpoint, or a configured fetchResourceToken stub returning an error.

Common situations: Misconfigured app credentials in config.toml, Feishu/Lark API outage or rate limiting on the token endpoint, firewall blocking open.feishu.cn, or an app that lost its permissions after a workspace change.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/6160db4b49bd6581. Report an issue: GitHub.