AprilNEA/OpenLogi · error
in-progress contribution contains unexpected entry
Error message
in-progress contribution contains unexpected entry {other:?}; refusing to publish over it What it means
Before publishing the fixture manifest, `validate_resumable_layout` audits every entry of the contribution directory against a known allowlist (state file, profile file, manifest file, cases directory). This bail fires when the directory contains a named entry that is none of those — the command refuses to publish over a directory holding unexpected files, because the final publish removes the state file and writes manifests in place and could clobber or mix in unknown content.
Solutions
- Remove or move the unexpected entry named in the message out of the contribution directory, then rerun the command.
- Check for hidden files (`ls -la DIR`) — backup files and OS metadata like `.DS_Store` often trigger this.
- Keep the contribution directory used exclusively by `openlogi fixture contribute`; do all other work elsewhere.
- If the entry is expected content the tool should allow, verify whether it belongs under `cases/` instead of the top level.
Example fix
# before ls fx/ -> profile.json state.json notes.txt openlogi fixture contribute --output fx ... # error: unexpected entry "notes.txt" # after mv fx/notes.txt ~/notes.txt openlogi fixture contribute --output fx ... # publishes
Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED: [&str; 4] = ["state.json", "profile.json", "manifest.json", "cases"];
fn has_foreign_entries(dir: &Path) -> anyhow::Result<bool> {
Ok(fs::read_dir(dir)?
.filter_map(Result::ok)
.any(|e| !e.file_name().to_str().map_or(true, |n| ALLOWED.contains(&n))))
}
// clean up any foreign entry before invoking the finish/publish phase Prevention
- Treat the contribution directory as write-only for the contribute tool; keep notes and logs elsewhere.
- Check `ls -la` for hidden backup/metadata files (.DS_Store, ~ backups) before the second run.
- Disable editor backup files while working near the directory.
- Finish the two-step workflow promptly instead of leaving the directory idle where other tools may touch it.
When it happens
Trigger: Running the publish/finish phase of `openlogi fixture contribute` (or the profile-only path) when DIR contains any extra file or subdirectory besides the expected state/profile/manifest/cases entries — e.g. editor backups, `.DS_Store`-style metadata, notes, or output from another tool written into the contribution directory.
Common situations: Editors or OS tools dropping backup/metadata files (`.DS_Store`, `profile.json~`, `Thumbs.db`) into DIR between step 1 and step 2; the user saving logs or notes inside the contribution folder; extracting an archive into DIR; a previous failed run leaving foreign files behind.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- already exists but is not an in-progress OpenLogi…
- in-progress contribution contains a non-UTF-8 entry
- saved contribution profile does not match its resumable…
- resumable fixture cases contain a non-UTF-8 entry
- resumable fixture cases contain unexpected file
AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13).
Data as JSON: /api/errors/9b5970ef30b257f3.
Report an issue: GitHub.
Appendix: source
Thrown at crates/openlogi-cli/src/cmd/fixture/contribute.rs:291
super::verify::run(&super::verify::VerifyArgs {
directory: directory.to_path_buf(),
})
}
fn validate_resumable_layout(directory: &Path, cassettes: &[HidCassette]) -> Result<()> {
for entry in
fs::read_dir(directory).context("could not inspect resumable contribution directory")?
{
let entry = entry.context("could not inspect resumable contribution entry")?;
let name = entry.file_name();
match name.to_str() {
Some(STATE_FILE | PROFILE_FILE) => {}
Some(MANIFEST_FILE) => require_regular_file(&entry.path(), "fixture manifest")?,
Some(CASES_DIRECTORY) if !cassettes.is_empty() => {
require_directory(&entry.path(), "fixture cases directory")?;
validate_resumable_cases(&entry.path(), cassettes)?;
}
Some(other) => bail!(
"in-progress contribution contains unexpected entry {other:?}; refusing to \
publish over it"
),
None => bail!("in-progress contribution contains a non-UTF-8 entry"),
}
}
Ok(())
}
fn validate_resumable_cases(directory: &Path, cassettes: &[HidCassette]) -> Result<()> {
let expected = cassettes
.iter()
.map(|cassette| format!("{}.json", cassette.name))
.collect::<Vec<_>>();
for entry in fs::read_dir(directory).context("could not inspect resumable fixture cases")? {
let entry = entry.context("could not inspect resumable fixture case")?;
let name = entry.file_name();
let Some(name) = name.to_str() else {View on GitHub (pinned to e846e6f4b4)