openai/codex · error · io::Error

memory import requires at least one selected memory

Error message

memory import requires at least one selected memory

What it means

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.

Source

Thrown at codex-rs/external-agent-migration/src/memory_import.rs:64

}

#[derive(Serialize)]
struct ProjectScope<'a> {
    cwd: &'a Path,
}

pub(super) async fn import(
    codex_home: &Path,
    external_agent_home: &Path,
    state_db: Option<&StateDbHandle>,
    selected_memory: &[String],
) -> io::Result<MemoryImportOutcome> {
    let selected_memory = selected_memory
        .iter()
        .map(String::as_str)
        .collect::<BTreeSet<_>>();
    if selected_memory.is_empty() {
        return Err(io::Error::new(
            io::ErrorKind::InvalidInput,
            "memory import requires at least one selected memory",
        ));
    }
    let state_db = state_db.ok_or_else(|| {
        io::Error::new(
            io::ErrorKind::NotConnected,
            "memory import requires the Codex state database",
        )
    })?;
    let memory_root = codex_home.join("memories");
    codex_memories_write::workspace::prepare_memory_workspace(&memory_root)
        .await
        .map_err(io::Error::other)?;
    let memory_files = discover_external_memory_files(external_agent_home)?;
    let copy_outcome = copy_resources(codex_home, &memory_files, &selected_memory)?;
    if copy_outcome.workspace_changed
        && let Err(err) = state_db

View on GitHub (pinned to 339751715c)

Solutions

  1. Guard the call: skip import entirely when selected_memory.is_empty()
  2. Fix the UI so the Import action is disabled until at least one discovered project is selected
  3. Populate the selection from the discovery result (discover_external_memory_files / projects_needing_import) instead of a hardcoded list

Example fix

// before
let outcome = import(&codex_home, &external_home, state_db, &selected).await?;

// after
if selected.is_empty() {
    return Ok(noop_outcome()); // nothing opted in - nothing to import
}
let outcome = import(&codex_home, &external_home, state_db, &selected).await?;
Defensive patterns

Strategy: validation

Validate before calling

if selected_memory.is_empty() {
    // user opted out - skip the call instead of triggering InvalidInput
    return Ok(noop_outcome());
}

Try / catch

match err.kind() {
    io::ErrorKind::InvalidInput if err.to_string().contains("at least one selected memory") => {
        // treat as a selection bug or no-op, not a fatal import failure
    }
    _ => return Err(err),
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


AI-assisted analysis of openai/codex@339751715c (2026-08-25). Data as JSON: /api/errors/fd6547e1e6828a9e. Report an issue: GitHub.