{"record":{"id":"fd6547e1e6828a9e","repo":"openai/codex","slug":"memory-import-requires-at-least-one-selected-memor","errorCode":null,"errorMessage":"memory import requires at least one selected memory","messagePattern":"memory import requires at least one selected memory","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"codex-rs/external-agent-migration/src/memory_import.rs","lineNumber":64,"sourceCode":"}\n\n#[derive(Serialize)]\nstruct ProjectScope<'a> {\n    cwd: &'a Path,\n}\n\npub(super) async fn import(\n    codex_home: &Path,\n    external_agent_home: &Path,\n    state_db: Option<&StateDbHandle>,\n    selected_memory: &[String],\n) -> io::Result<MemoryImportOutcome> {\n    let selected_memory = selected_memory\n        .iter()\n        .map(String::as_str)\n        .collect::<BTreeSet<_>>();\n    if selected_memory.is_empty() {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidInput,\n            \"memory import requires at least one selected memory\",\n        ));\n    }\n    let state_db = state_db.ok_or_else(|| {\n        io::Error::new(\n            io::ErrorKind::NotConnected,\n            \"memory import requires the Codex state database\",\n        )\n    })?;\n    let memory_root = codex_home.join(\"memories\");\n    codex_memories_write::workspace::prepare_memory_workspace(&memory_root)\n        .await\n        .map_err(io::Error::other)?;\n    let memory_files = discover_external_memory_files(external_agent_home)?;\n    let copy_outcome = copy_resources(codex_home, &memory_files, &selected_memory)?;\n    if copy_outcome.workspace_changed\n        && let Err(err) = state_db","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/openai/codex/blob/339751715c64496cb86246bfb3935f40e309dd3d/codex-rs/external-agent-migration/src/memory_import.rs#L46-L82","documentation":"The external-agent memory import returns io::Error(InvalidInput, 'memory import requires at least one selected memory') when the selected_memory slice passed to import() is empty (codex-rs/external-agent-migration/src/memory_import.rs:63-68). Importing external-agent memory (for example Claude Code memory directories) into Codex memories is opt-in per project key; an empty selection is treated as a caller bug rather than a no-op.","triggerScenarios":"Calling import(codex_home, external_agent_home, state_db, &[]) - a migration wizard invoked with no projects checked, or a programmatic caller forwarding an empty selection list.","commonSituations":"A UI where 'select none' plus Import is still possible; callers that build the selection by filtering and the filter matches nothing; flows that skip the discovery step and pass a default-empty Vec.","solutions":["Guard the call: skip import entirely when selected_memory.is_empty()","Fix the UI so the Import action is disabled until at least one discovered project is selected","Populate the selection from the discovery result (discover_external_memory_files / projects_needing_import) instead of a hardcoded list"],"exampleFix":"// before\nlet outcome = import(&codex_home, &external_home, state_db, &selected).await?;\n\n// after\nif selected.is_empty() {\n    return Ok(noop_outcome()); // nothing opted in - nothing to import\n}\nlet outcome = import(&codex_home, &external_home, state_db, &selected).await?;","handlingStrategy":"validation","validationCode":"if selected_memory.is_empty() {\n    // user opted out - skip the call instead of triggering InvalidInput\n    return Ok(noop_outcome());\n}","typeGuard":null,"tryCatchPattern":"match err.kind() {\n    io::ErrorKind::InvalidInput if err.to_string().contains(\"at least one selected memory\") => {\n        // treat as a selection bug or no-op, not a fatal import failure\n    }\n    _ => return Err(err),\n}","preventionTips":["Derive the selection from the discovery scan, never a default empty Vec","Disable import actions in UI states where the selection is empty","Treat an empty selection as 'user opted out', not as an import request"],"tags":["migration","memory-import","input-validation","rust"],"backgroundTag":"missing-required-parameter","analyzedSha":"339751715c64496cb86246bfb3935f40e309dd3d","analyzedAt":"2026-08-25T05:35:09.876Z","schemaVersion":2},"datasetVersion":"2026-08-25T06:17:31.827Z"}