larksuite/cli · error

[%d] %s

Error message

[%d] %s

What it means

VerifyUserToken parsed the verification response successfully, but the API-level business code was non-zero. The error message is '[code] msg' — the Feishu API's own code and message pair indicating token verification was rejected (invalid, expired, or unauthorized token). This is a server-side semantic failure, not a transport problem.

Source

Thrown at internal/auth/verify.go:37

	apiResp, err := sdk.Do(ctx, &larkcore.ApiReq{
		HttpMethod:                http.MethodGet,
		ApiPath:                   PathUserInfoV1,
		SupportedAccessTokenTypes: []larkcore.AccessTokenType{larkcore.AccessTokenTypeUser},
	}, larkcore.WithUserAccessToken(accessToken))
	if err != nil {
		return err
	}
	logSDKResponse(PathUserInfoV1, apiResp)

	var resp struct {
		Code int    `json:"code"`
		Msg  string `json:"msg"`
	}
	if err := json.Unmarshal(apiResp.RawBody, &resp); err != nil {
		return fmt.Errorf("failed to parse response: %w", err)
	}
	if resp.Code != 0 {
		return fmt.Errorf("[%d] %s", resp.Code, resp.Msg)
	}
	return nil
}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Look up the embedded code in the Feishu error-code docs to identify the exact rejection reason (expired vs invalid vs permission).
  2. If the token is expired, re-run the login/device flow to obtain a fresh token and retry verification.
  3. Verify the app_id/app_secret used for verification match the app that issued the token.
  4. Check system clock skew (NTP) if the code indicates an expired but recently issued token.
Defensive patterns

Strategy: try-catch

Validate before calling

// check token freshness before verification
type tok interface{ ExpiresAt() time.Time }
if t, ok := token.(tok); ok && time.Now().After(t.ExpiresAt()) {
    token = relogin(ctx) // refresh before verifying
}

Type guard

func isBizReject(err error) (code int, msg string, ok bool) {
    s := err.Error()
    if strings.HasPrefix(s, "[") {
        if n, _ := fmt.Sscanf(s, "[%d]", &code); n == 1 { return code, s, true }
    }
    return 0, s, false
}

Try / catch

if err := auth.VerifyUserToken(ctx, tok); err != nil {
    if code, msg, ok := isBizReject(err); ok {
        switch code {
        case errExpired:
            return reauthAndRetry(ctx)
        default:
            return fmt.Errorf("token rejected by API (code %d): %s", code, msg)
        }
    }
    return err
}

Prevention

When it happens

Trigger: resp.Code != 0 after unmarshalling the verify response — e.g. token invalid/expired/revoked, wrong app identity, or missing permission for the verification endpoint.

Common situations: User token expired between issuance and verification; token belongs to a different app (app_id/app_secret mismatch after config change); token revoked by logout; clock skew making the token appear expired.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/c62ee0c2b5f0d7a3. Report an issue: GitHub.