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
- Look up the embedded code in the Feishu error-code docs to identify the exact rejection reason (expired vs invalid vs permission).
- If the token is expired, re-run the login/device flow to obtain a fresh token and retry verification.
- Verify the app_id/app_secret used for verification match the app that issued the token.
- 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
- Refresh/re-login before tokens expire instead of verifying stale tokens.
- Ensure app_id/app_secret used for verification match the token-issuing app.
- Sync system clocks (NTP) to avoid false expiry.
- Map known Feishu error codes to recovery actions (re-login vs config fix).
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
- failed to get user info [%d]: %s
- failed to parse response: %w
- fetch bot info: HTTP %d
- Invalid column: {column!r}
- Invalid column index: {index}
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/c62ee0c2b5f0d7a3.
Report an issue: GitHub.