astrid-runtime/astrid · error

unexpected entry in released legacy SurrealKV source: {}

Error message

unexpected entry in released legacy SurrealKV source: {}

What it means

validate_legacy_surrealkv_entry whitelists exactly which entries may appear in a released legacy SurrealKV source directory. Any entry failing that whitelist check (e.g. unexpected regular file, wrong file type at a known name) causes InvalidData with the relative path. This guard runs before deletion so retirement never destroys unrecognized data.

Source

Thrown at crates/astrid-core/src/dirs_layout_retirement.rs:177

        },
        [directory, name] if directory.as_os_str() == "wal" && is_file => {
            is_numbered_legacy_file(name.as_os_str(), b".wal")
        },
        [directory, name] if directory.as_os_str() == "sstables" && is_file => {
            is_numbered_legacy_file(name.as_os_str(), b".sst")
        },
        [directory, name] if directory.as_os_str() == "vlog" && is_file => {
            is_numbered_legacy_file(name.as_os_str(), b".vlog")
        },
        [directory, name]
            if directory.as_os_str() == "versioned_index" && name.as_os_str() == "index.bpt" =>
        {
            is_file
        },
        _ => false,
    };
    if !valid {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!(
                "unexpected entry in released legacy SurrealKV source: {}",
                relative.display()
            ),
        ));
    }
    Ok(())
}

fn is_numbered_legacy_file(name: &std::ffi::OsStr, extension: &[u8]) -> bool {
    let bytes = name.as_encoded_bytes();
    bytes.split_at_checked(20).is_some_and(|(digits, suffix)| {
        digits.iter().all(u8::is_ascii_digit) && suffix == extension
    })
}

pub(super) fn retire_legacy_source_tree(path: &Path) -> io::Result<()> {

View on GitHub (pinned to affd8760f4)

Solutions

  1. Move the unexpected entry out of the legacy SurrealKV directory (archive it elsewhere), then retry retirement.
  2. Compare the directory against the expected released layout and remove or rename stray artifacts.
  3. If the entry is legitimate new-version data, abort retirement — the validator indicates this tree is not the legacy shape it expects.

Example fix

// before
legacy/surrealkv/{data/, extra.log}
// after
mv legacy/surrealkv/extra.log ~/archive/extra.log
Defensive patterns

Strategy: validation

Validate before calling

fn assert_known_layout(dir: &Path, allowed: &[&str]) -> io::Result<()> {
    for e in std::fs::read_dir(dir)? {
        let name = e?.file_name().to_string_lossy().into_owned();
        if !allowed.contains(&name.as_str()) {
            return Err(io::Error::new(io::ErrorKind::InvalidData, format!("unexpected: {name}")));
        }
    }
    Ok(())
}

Type guard

fn is_whitelisted(rel: &Path, allowed: &[&str]) -> bool {
    rel.to_str().map(|s| allowed.contains(&s)).unwrap_or(false)
}

Try / catch

match retire_legacy_source_tree(&path, dev) {
    Err(e) if e.to_string().contains("unexpected entry") => archive_stray_entries(&path)?,
    other => other?,
}

Prevention

When it happens

Trigger: Calling retire_legacy_source_tree on a legacy SurrealKV dir whose contents include anything beyond the expected released layout (extra files, missing expected files, unexpected file/dir type at a known path).

Common situations: User data or logs were written into the SurrealKV directory; a partially applied migration left extra artifacts; an older/newer version created files the validator doesn't know.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/ba3a9fccd294422c. Report an issue: GitHub.