Wei-Shaw/sub2api · error
未包含 refresh_token,且无法解析 accessToken 过期时间;请在第一步设置过期时间后再导入
Error message
未包含 refresh_token,且无法解析 accessToken 过期时间;请在第一步设置过期时间后再导入
What it means
Returned by resolveCodexImportExpiry (backend/internal/handler/admin/account_codex_import.go:805) when an import entry has no refresh_token AND no expiry can be determined — neither a parseable exp claim from the access token (item.TokenExpiresAt is nil) nor a request-level req.ExpiresAt. Without any expiry the scheduler cannot auto-stop the account, so the import is refused and the admin is told to set an expiry in step one of the import flow.
Source
Thrown at backend/internal/handler/admin/account_codex_import.go:805
t := time.Unix(*req.ExpiresAt, 0).UTC()
requestExpiresAt = &t
}
var accountExpiresAt *time.Time
var credentialExpiresAt *time.Time
warnings := make([]string, 0, 2)
if item.RefreshToken == "" {
if item.TokenExpiresAt != nil {
tokenExpiresAt := item.TokenExpiresAt.UTC()
accountExpiresAt = &tokenExpiresAt
credentialExpiresAt = &tokenExpiresAt
}
if requestExpiresAt != nil {
accountExpiresAt = earlierCodexTime(accountExpiresAt, requestExpiresAt)
credentialExpiresAt = earlierCodexTime(credentialExpiresAt, requestExpiresAt)
}
if accountExpiresAt == nil {
return nil, nil, nil, nil, errors.New("未包含 refresh_token,且无法解析 accessToken 过期时间;请在第一步设置过期时间后再导入")
}
if accountExpiresAt.Unix() <= time.Now().UTC().Unix()-codexImportClockSkewSeconds {
return nil, nil, nil, nil, fmt.Errorf("过期时间已过期: %s", accountExpiresAt.Format(time.RFC3339))
}
warnings = append(warnings, "未包含 refresh_token,已按 accessToken/账号过期时间设置自动停止调度")
if req.AutoPauseOnExpired != nil && !*req.AutoPauseOnExpired {
warnings = append(warnings, "未包含 refresh_token,已强制开启过期自动暂停")
}
autoPause := true
expiresAtUnix := accountExpiresAt.Unix()
return &expiresAtUnix, credentialExpiresAt, &autoPause, warnings, nil
}
if requestExpiresAt != nil {
accountExpiresAt = requestExpiresAt
}
if item.TokenExpiresAt != nil {
tokenExpiresAt := item.TokenExpiresAt.UTC()View on GitHub (pinned to 073e92d171)
Solutions
- Set ExpiresAt (unix seconds) on the import request to the token's known expiry, then re-import.
- Include a refresh_token in the entry so the account can renew and the expiry policy does not apply.
- If the access token is a JWT, verify it still carries a valid exp claim (decode it) — if parseable, TokenExpiresAt is populated automatically and this error disappears.
- If the token really has no refresh and unknown expiry, obtain a fresh token first.
Example fix
// before
POST /admin/codex/import
{ "items": [ { "accessToken": "opaque-token-no-exp" } ] }
// after
POST /admin/codex/import
{ "expiresAt": 1770000000, "items": [ { "accessToken": "opaque-token-no-exp" } ] } Defensive patterns
Strategy: validation
Validate before calling
function canResolveExpiry(entry: { refresh_token?: string; accessToken?: string }, reqExpiresAt?: number): boolean {
if (entry.refresh_token && entry.refresh_token.length > 0) return true
if (typeof reqExpiresAt === 'number' && reqExpiresAt > 0) return true
try {
const payload = JSON.parse(atob(entry.accessToken!.split('.')[1]))
return typeof payload.exp === 'number' && payload.exp > 0
} catch { return false }
} Prevention
- In the import wizard's first step, always set ExpiresAt when the entry has no refresh_token.
- Prefer exports that include refresh_token so expiry policy is unnecessary.
- Decode the JWT locally to confirm it carries an exp claim before importing opaque tokens.
- Note the related failure '过期时间已过期' when the resolved expiry is already in the past (minus clock skew).
When it happens
Trigger: Importing a Codex auth.json lacking refresh_token where the accessToken is opaque (exp not parseable) and the import request's ExpiresAt field is unset or zero. The nearby branch also rejects entries whose resolved expiry is already past ('过期时间已过期').
Common situations: Short-lived demo tokens pasted without metadata; JWTs signed with an unreadable/expired exp; admin skipping the 'set expiry' step in the two-step import wizard; exporting tokens from a tool that strips refresh tokens.
Related errors
- 空 JSON 内容
- agent identity 缺少必要字段
- agent identity private key 格式无效
- 缺少 accessToken/access_token
- proxies is required
AI-assisted analysis of Wei-Shaw/sub2api@073e92d171 (2026-08-15).
Data as JSON: /api/errors/a6907a564b5b0bba.
Report an issue: GitHub.