GraphiteEditor/Graphite · warning
just checked there's one entry
Error message
just checked there's one entry
What it means
In the crash-recovery flow, files is a collected Vec and the code branches on files.len() == 1, then immediately does files.into_iter().next().expect("just checked there's one entry"). This expect is an invariant annotation for the compiler: the length was just checked, so next() must yield Some. It is unreachable unless the two collections diverge (e.g., a future refactor checks one Vec but iterates another).
Source
Thrown at editor/src/messages/portfolio/portfolio_message_handler.rs:500
let base = format!("{stem}.{FILE_EXTENSION}");
let unique = match used_names.get(&base).copied() {
None => {
used_names.insert(base.clone(), 1);
base
}
Some(n) => {
used_names.insert(base.clone(), n + 1);
format!("{stem} ({n}).{FILE_EXTENSION}")
}
};
(unique, content.as_bytes().to_vec())
})
.collect();
const FOLDER_NAME: &str = "Graphite Recovered Documents";
if files.len() == 1 {
let (filename, content) = files.into_iter().next().expect("just checked there's one entry");
responses.add(FrontendMessage::TriggerSaveFile {
name: filename,
folder: None,
content: serde_bytes::ByteBuf::from(content),
});
} else {
match build_recovery_zip(&files) {
Ok(zip_bytes) => responses.add(FrontendMessage::TriggerSaveFile {
name: format!("{FOLDER_NAME}.zip"),
folder: None,
content: serde_bytes::ByteBuf::from(zip_bytes),
}),
Err(e) => {
log::error!("Failed to build recovery zip: {e}");
responses.add(DialogMessage::DisplayDialogError {
title: "Failed to download".to_string(),
description: format!("Could not bundle the failed documents for download.\n\n{e}"),
});View on GitHub (pinned to c507b35645)
Solutions
- Prefer if let Some((filename, content)) = files.into_iter().next() which makes the branch and the extraction one atomic pattern
- Keep the length check and the drain adjacent so refactors cannot separate them
- If kept as-is, treat any hit of this expect as a logic-bug signal, not an environment problem
Example fix
// before
if files.len() == 1 {
let (filename, content) = files.into_iter().next().expect("just checked there's one entry");
// ...
}
// after
if let Some((filename, content)) = files.into_iter().next_if(|_| files.len() == 1) {
// ...
} Defensive patterns
Strategy: validation
Validate before calling
if files.len() == 1 {
debug_assert_eq!(files.len(), 1);
if let Some((filename, content)) = files.into_iter().next() { /* handle single file */ }
} Prevention
- Fuse the length check and the extraction into one pattern (if let) so refactors cannot split the invariant
- Treat any hit of such an 'unreachable' expect as a logic bug introduced by recent changes
- Avoid duplicating this pattern in async contexts where state can change between check and use
When it happens
Trigger: Practically unreachable as written; would fire only if the len()==1 check and the iterated collection become different collections after refactoring, or concurrency were introduced between check and use (there is none here).
Common situations: Refactors that split or rebuild the files Vec between the length check and iteration; copy-paste of this pattern into async code where the invariant no longer holds.
Related errors
- Ungrouped folder must have a parent
- Failed to create artboard node
- In `check_layer()`: there should be a `target`
- Parent accessed via child should have children
- Handle cannot be converted
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/bddf3e01114a604a.
Report an issue: GitHub.