{"record":{"id":"0a323b94d5030028","repo":"BigPizzaV3/CodexPlusPlus","slug":"work-dir","errorCode":null,"errorMessage":"工作目录不存在：{work_dir}","messagePattern":"工作目录不存在：(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/connect/mod.rs","lineNumber":152,"sourceCode":"}\n\npub async fn run_weixin_connect_with_codex_path(\n    config: WeixinConnectConfig,\n    stop: Arc<AtomicBool>,\n    status: SharedWeixinConnectStatus,\n    codex_path: WeixinCodexPath,\n) -> anyhow::Result<()> {\n    let config = config.normalized();\n    if config.token.is_empty() {\n        bail!(\"请先扫码登录微信\");\n    }\n    let work_dir = if config.work_dir.is_empty() {\n        std::env::current_dir().context(\"无法读取当前工作目录\")?\n    } else {\n        PathBuf::from(&config.work_dir)\n    };\n    if !work_dir.is_dir() {\n        bail!(\"工作目录不存在：{}\", work_dir.display());\n    }\n\n    update_status(&status, |current| {\n        current.state = \"starting\".to_string();\n        current.message = \"正在连接微信和 Codex app-server...\".to_string();\n        current.account_id = config.account_id.clone();\n        current.has_token = true;\n    });\n\n    let client = WeixinClient::new(&config.base_url, &config.token, &config.route_tag)?;\n    let store = ConnectSessionStore::default_for_account(&config.account_id);\n    let mut state = store.load().unwrap_or_default();\n    let mut app_config = AppServerConfig {\n        executable: config.codex_path.clone(),\n        work_dir,\n        model: config.model.clone(),\n        sandbox: config.sandbox.clone(),\n    };","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/crates/codex-plus-core/src/connect/mod.rs#L134-L170","documentation":"The WeChat connect flow resolves its working directory from config.work_dir, falling back to the current process directory, and validates that the path is an existing directory before spawning anything. When the path is missing or is a file, it bails with this message including the resolved path. This prevents the bridge from creating state in unexpected or nonexistent locations.","triggerScenarios":"Calling run_weixin_connect with a WeixinConfig whose `work_dir` points to a path that does not exist or is not a directory (after fallback to std::env::current_dir() when work_dir is empty).","commonSituations":"Typo in the configured work_dir path; directory deleted after being configured; work_dir points to a file; the fallback CWD was removed (process started in a deleted directory).","solutions":["Create the configured directory: mkdir -p <work_dir>","Fix config.work_dir to point to an existing directory (verify with ls)","Clear work_dir to empty so the process current directory is used instead"],"exampleFix":"// before\nconfig.work_dir = \"/home/user/codex-state\"; // directory deleted\nrun_weixin_connect(config).await?;\n// after\nstd::fs::create_dir_all(\"/home/user/codex-state\")?; // ensure it exists\nconfig.work_dir = \"/home/user/codex-state\";\nrun_weixin_connect(config).await?;","handlingStrategy":"validation","validationCode":"let wd = if config.work_dir.is_empty() { std::env::current_dir()? } else { PathBuf::from(&config.work_dir) };\nif !wd.is_dir() { std::fs::create_dir_all(&wd)?; }","typeGuard":"fn work_dir_exists(c: &WeixinConfig) -> bool {\n    let p = if c.work_dir.is_empty() { std::env::current_dir().unwrap_or_default() } else { PathBuf::from(&c.work_dir) };\n    p.is_dir()\n}","tryCatchPattern":"match run_weixin_connect(config).await {\n    Err(e) if e.to_string().contains(\"工作目录不存在\") => { create_dir_and_retry()?; }\n    other => other,\n}","preventionTips":["Create the work_dir with create_dir_all at app startup","Validate configured paths in the settings UI before saving","Avoid configuring work_dir to a removable/network path that may vanish","Prefer empty work_dir (CWD fallback) only when launch CWD is stable"],"tags":["filesystem","config","directory","rust"],"backgroundTag":"directory-not-found","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}