{"record":{"id":"f92852a7d4ddcf6b","repo":"jlcodes99/cockpit-tools","slug":"oauth","errorCode":null,"errorMessage":"OAuth 回调服务器错误: {}","messagePattern":"OAuth 回调服务器错误: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cockpit-core/src/modules/codex_oauth.rs","lineNumber":228,"sourceCode":"    match TcpListener::bind((\"127.0.0.1\", state.port)) {\n        Ok(listener) => {\n            drop(listener);\n            let expected_state = state.state.clone();\n            let expected_login_id = state.login_id.clone();\n            let callback_url = state.redirect_uri.clone();\n            let app_handle_clone = app_handle.clone();\n            let port = state.port;\n            tokio::spawn(async move {\n                if let Err(e) = start_callback_server(\n                    port,\n                    expected_state,\n                    expected_login_id,\n                    callback_url,\n                    app_handle_clone,\n                )\n                .await\n                {\n                    logger::log_error(&format!(\"OAuth 回调服务器错误: {}\", e));\n                }\n            });\n            logger::log_info(&format!(\n                \"Codex OAuth 已恢复回调监听: login_id={}, port={}\",\n                state.login_id, state.port\n            ));\n        }\n        Err(err) if err.kind() == ErrorKind::AddrInUse => {\n            logger::log_info(&format!(\n                \"Codex OAuth 回调端口已占用，视为监听中: login_id={}, port={}\",\n                state.login_id, state.port\n            ));\n        }\n        Err(err) => {\n            logger::log_warn(&format!(\n                \"Codex OAuth 回调监听恢复失败: login_id={}, port={}, error={}\",\n                state.login_id, state.port, err\n            ));","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/crates/cockpit-core/src/modules/codex_oauth.rs#L210-L246","documentation":"When restoring a pending Codex OAuth session, ensure_callback_listener_for_state spawns a background task that runs the local HTTP callback server. If that server task returns an error (bind failure, port conflict, handler crash), it is logged as 'OAuth 回调服务器错误'. The OAuth flow cannot receive the provider's redirect until this server is listening.","triggerScenarios":"App restart with a persisted OAuth state whose port is now occupied by another process; firewall blocking the local listener; bind to 127.0.0.1:<port> failing because the port is in TIME_WAIT or reserved.","commonSituations":"Port taken by another instance of the app or unrelated service after reboot; stale pending OAuth state restored long after the session expired; security software blocking local socket binding.","solutions":["Check whether the callback port is occupied (lsof -i :<port> / netstat) and free it or restart the conflicting service","Clear/restart the pending OAuth login so a fresh port is allocated","Retry start_oauth_login to create a new session and listener","Check firewall/antivirus rules that may block binding a local HTTP listener"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// before restoring, check the port is bindable\nuse std::net::TcpListener;\nfn port_free(port: u16) -> bool {\n    TcpListener::bind((\"127.0.0.1\", port)).is_ok()\n}","typeGuard":null,"tryCatchPattern":"match restore_pending_oauth_listener(app).await {\n    Ok(_) => {},\n    Err(e) if format!(\"{e}\").contains(\"OAuth 回调服务器错误\") => {\n        // port blocked/stale state: clear pending state and start a fresh login\n        clear_pending_oauth_state(app);\n        start_oauth_login(app).await?;\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Clear stale pending OAuth state after app crashes/restarts","Avoid running multiple simultaneous OAuth logins","Whitelist localhost listener ports in firewall/AV software","Check port availability before restoring a persisted listener"],"tags":["oauth","codex","network","callback-server"],"backgroundTag":"oauth-callback-server-error","analyzedSha":"1ed8b77992d62ca81fabf744deb0839ad361d5bf","analyzedAt":"2026-09-05T09:51:41.178Z","contentChangedAt":"2026-09-05T09:51:41.178Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}