{"record":{"id":"a756c86ca5a4dac9","repo":"Wei-Shaw/sub2api","slug":"accesstoken-access-token","errorCode":null,"errorMessage":"缺少 accessToken/access_token","messagePattern":"缺少 accessToken/access_token","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/internal/handler/admin/account_codex_import.go","lineNumber":625,"sourceCode":"\t\t\t\treturn nil, fmt.Errorf(\"access_token 已过期: %s\", tokenExpiresAt.Format(time.RFC3339))\n\t\t\t}\n\t\t\titem.TokenExpiresAt = &tokenExpiresAt\n\t\t\titem.Credentials[\"expires_at\"] = tokenExpiresAt.Format(time.RFC3339)\n\t\t}\n\t\tcopyCodexExtraString(raw, item.Extra, \"user_image\", []string{\"user\", \"image\"})\n\t\tcopyCodexExtraString(raw, item.Extra, \"user_picture\", []string{\"user\", \"picture\"})\n\t\tcopyCodexExtraString(raw, item.Extra, \"account_structure\", []string{\"account\", \"structure\"})\n\t\tcopyCodexExtraString(raw, item.Extra, \"account_residency_region\", []string{\"account\", \"residencyRegion\"})\n\t\tcopyCodexExtraString(raw, item.Extra, \"compute_residency\", []string{\"account\", \"computeResidency\"})\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"第 %d 条格式不支持\", entry.Index)\n\t}\n\n\tif item.IsAgentIdentity {\n\t\treturn item, nil\n\t}\n\tif item.AccessToken == \"\" {\n\t\treturn nil, errors.New(\"缺少 accessToken/access_token\")\n\t}\n\titem.Credentials[\"access_token\"] = item.AccessToken\n\tif item.RefreshToken != \"\" {\n\t\titem.Credentials[\"refresh_token\"] = item.RefreshToken\n\t\titem.Credentials[\"client_id\"] = openai.ClientID\n\t}\n\tif item.IDToken != \"\" {\n\t\titem.Credentials[\"id_token\"] = item.IDToken\n\t\t_ = enrichCodexImportAccountFromJWT(item, item.IDToken, false, now)\n\t}\n\tif err := enrichCodexImportAccountFromJWT(item, item.AccessToken, true, now); err != nil {\n\t\treturn nil, err\n\t}\n\tif _, ok := item.Credentials[\"expires_at\"]; !ok {\n\t\titem.WarningTexts = append(item.WarningTexts, \"无法从 accessToken 解析过期时间，导入后需自行确认令牌有效性\")\n\t}\n\tif item.RefreshToken == \"\" {\n\t\titem.WarningTexts = append(item.WarningTexts, \"未包含 refresh_token，accessToken 过期后无法自动续期\")","sourceCodeStart":607,"sourceCodeEnd":643,"githubUrl":"https://github.com/Wei-Shaw/sub2api/blob/073e92d17178a1ccdb0a27017f572f10c9c7ab62/backend/internal/handler/admin/account_codex_import.go#L607-L643","documentation":"Returned at backend/internal/handler/admin/account_codex_import.go:625 for a non-agent-identity Codex import entry whose AccessToken is empty after all supported format extractions ran (the switch above already rejected unsupported formats with '第 N 条格式不支持'). OAuth-type Codex accounts must carry an access token; agent-identity entries are exempted earlier (item.IsAgentIdentity returns before this check).","triggerScenarios":"Importing a Codex auth.json that has a refresh_token or id_token but no accessToken/access_token field (or it is null/empty); an entry format that matched but maps the token under an unrecognized key.","commonSituations":"Exporting from a Codex CLI version that stores the token under a different key; hand-trimming the access token for privacy before import; a partially-written auth.json because the source process was interrupted mid-refresh.","solutions":["Include a non-empty accessToken (or access_token) in the entry and re-import.","If the token lives under a different key in your export, rename it to accessToken/access_token first.","If you only have an agent identity (no OAuth token), import it as an agent-identity entry so the check is skipped.","Re-run 'codex login' / re-export to regenerate a complete auth.json."],"exampleFix":"// before\n{ \"refresh_token\": \"rt_...\", \"id_token\": \"eyJ...\" }\n\n// after\n{ \"accessToken\": \"eyJ...\", \"refresh_token\": \"rt_...\", \"id_token\": \"eyJ...\" }","handlingStrategy":"validation","validationCode":"function hasAccessToken(entry: Record<string, unknown>): boolean {\n  const t = entry.accessToken ?? entry.access_token\n  return typeof t === 'string' && t.trim() !== ''\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Before import, confirm the auth.json has a non-empty accessToken/access_token.","If you only hold an agent identity, mark the entry as agent identity so the OAuth token check is skipped.","Re-run the CLI login to regenerate a complete auth.json instead of hand-assembling one.","Beware exports from other Codex versions that rename token keys."],"tags":["admin","import","oauth","access-token","validation","backend","codex"],"backgroundTag":null,"analyzedSha":"073e92d17178a1ccdb0a27017f572f10c9c7ab62","analyzedAt":"2026-08-15T14:33:00.750Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}