{"record":{"id":"8d2cc5a43a72ddae","repo":"larksuite/cli","slug":"stored-token-data-is-corrupt","errorCode":null,"errorMessage":"stored token data is corrupt","messagePattern":"stored token data is corrupt","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/auth/token_store.go","lineNumber":30,"sourceCode":"\t\"github.com/larksuite/cli/errs\"\n\t\"github.com/larksuite/cli/internal/keychain\"\n)\n\n// StoredUAToken represents a stored user access token.\ntype StoredUAToken struct {\n\tUserOpenId       string `json:\"userOpenId\"`\n\tAppId            string `json:\"appId\"`\n\tAccessToken      string `json:\"accessToken\"`\n\tRefreshToken     string `json:\"refreshToken\"`\n\tExpiresAt        int64  `json:\"expiresAt\"`        // Unix ms\n\tRefreshExpiresAt int64  `json:\"refreshExpiresAt\"` // Unix ms\n\tScope            string `json:\"scope\"`\n\tGrantedAt        int64  `json:\"grantedAt\"` // Unix ms\n}\n\nconst refreshAheadMs = 5 * 60 * 1000 // 5 minutes\n\nvar errStoredTokenCorrupt = errors.New(\"stored token data is corrupt\")\n\n// accountKey generates a unique key for an account based on its AppID and UserOpenID.\nfunc accountKey(appId, userOpenId string) string {\n\treturn fmt.Sprintf(\"%s:%s\", appId, userOpenId)\n}\n\n// MaskToken masks a token for safe logging.\nfunc MaskToken(token string) string {\n\tif len(token) <= 8 {\n\t\treturn \"****\"\n\t}\n\treturn \"****\" + token[len(token)-4:]\n}\n\n// GetStoredToken reads the stored UAT for a given (appId, userOpenId) pair.\nfunc GetStoredToken(appId, userOpenId string) *StoredUAToken {\n\ttoken, _ := readStoredToken(appId, userOpenId)\n\treturn token","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/auth/token_store.go#L12-L48","documentation":"errStoredTokenCorrupt signals that a stored user access token could not be decoded back into a StoredUAToken struct — the persisted token blob is damaged, truncated, or was written by an incompatible format. readStoredToken wraps the decode failure with this sentinel, and GetValidAccessToken maps it to a NeedUserAuthorization error because a corrupt token is unusable and only re-authorization can recover it. The library throws it so callers can distinguish 'token corrupt' from 'token missing' and force an interactive re-auth.","triggerScenarios":"Calling GetValidAccessToken (or readStoredToken) when the token file/record for appId:userOpenId contains bytes that fail JSON unmarshal — e.g. partial write, manual tampering, or format change across CLI versions.","commonSituations":"Disk full during token write; user edited or deleted part of the token store; upgrading lark-cli after the stored token schema changed; a sandbox/backup tool mangled the token file.","solutions":["Re-authenticate the user: run the CLI's authorization flow so the token is rewritten (GetValidAccessToken already surfaces NeedUserAuthorization for this)","Delete the corrupt token entry for the affected appId:userOpenId and log in again","Check disk space and file permissions on the token store location","If reproducible across versions, report the token schema change"],"exampleFix":"// before\nstored, err := readStoredToken(appId, openId)\nif err != nil { return err }\n// after\nstored, err := readStoredToken(appId, openId)\nif errors.Is(err, errStoredTokenCorrupt) {\n    return newNeedUserAuthorizationError(openId, err, recovery.UserAuthorization())\n}","handlingStrategy":"try-catch","validationCode":"// verify stored token decodes before use\nif _, err := readStoredToken(appId, openId); errors.Is(err, errStoredTokenCorrupt) {\n    // token file unreadable — require re-auth\n}","typeGuard":"func isCorruptToken(err error) bool { return errors.Is(err, errStoredTokenCorrupt) }","tryCatchPattern":"token, err := GetValidAccessToken(client, opts)\nif errors.Is(err, errStoredTokenCorrupt) {\n    return reauthorize(opts.UserOpenId) // map to NeedUserAuthorization\n}","preventionTips":["Never hand-edit the token store files","Ensure writes to the token store complete atomically (temp file + rename)","Back up token store before upgrading CLI versions","Monitor disk space where tokens are persisted"],"tags":["auth","token-store","corruption"],"backgroundTag":"corrupt-stored-token","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}