ramensoftware/windhawk · warning
the mod has no recorded version, so it was not exported
Error message
the mod has no recorded version, so it was not exported
What it means
During user-data export, a mod whose installed entry has an empty recorded version cannot be represented in the archive (ArchiveMod requires a version), so it is skipped and a per-mod ExportWarning with this message is emitted. Export continues for other mods.
Solutions
- Reinstall the mod so its version is recorded, then re-export
- Ensure the mod's source carries a proper `// ==WindhawkMod== @version` header
- Drop the mod from the export selection
- Verify the mod shows a version in the Windhawk UI before exporting
Example fix
// before // ==WindhawkMod== // @id my-mod // ==/WindhawkMod== // after // ==WindhawkMod== // @id my-mod // @version 1.0.1 // ==/WindhawkMod==
Defensive patterns
Strategy: validation
Validate before calling
// before export: check every selected mod has a recorded version
for m in installed_mods.filter(|m| selection.includes(&m.id)) {
if m.version.is_empty() { eprintln!("{}: no version, will be skipped", m.id); }
} Type guard
fn has_version(entry: &InstalledModListEntry) -> bool {
!entry.version.as_deref().unwrap_or("").is_empty()
} Prevention
- Keep @version headers in mod sources intact
- Complete interrupted installs before exporting
- Check export warnings for skipped mods after every export
When it happens
Trigger: Running `windhawk data export` while selecting a mod whose storage entry lacks a version — e.g. an install that never completed version recording or a hand-edited config mirror missing @version.
Common situations: Crashed or interrupted mod installs; mods installed by old versions that didn't record the version; corrupted mod storage state.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- {}: {}
- the mod's source , so it was not exported
- the mod source , so its settings were not exported; this…
- INVALID_REQUEST
- Failed to load metadata for mod
AI-assisted analysis of ramensoftware/windhawk@61d99ed8e1 (2026-09-12).
Data as JSON: /api/errors/eca41d9d6942c9ce.
Report an issue: GitHub.
Appendix: source
Thrown at src/windhawk-core/core/src/services/user_data.rs:193
}
/// Build one mod's archive entry, or `None` when it cannot be represented (a
/// local mod with no usable source, a mod with no recorded version, or an entry
/// the archive format itself refuses); a per-mod issue is pushed onto
/// `warnings` in every case.
fn export_mod(
session: &SessionInner,
selection: &UserDataSelection,
offline: bool,
language: &str,
id: &str,
entry: &InstalledModListEntry,
warnings: &mut Vec<ExportWarning>,
) -> Result<Option<ArchiveMod>, CoreError> {
let is_local = ModId::str_is_local(id);
let version = installed_version(entry);
if version.is_empty() {
warnings.push(warn(
id,
"the mod has no recorded version, so it was not exported",
));
return Ok(None);
}
let name = entry.metadata.as_ref().and_then(|m| m.name.clone());
let (want_settings, want_config) = facet_toggles(selection, id);
// A repository mod's source embeds only under an offline export; a local
// mod's source is always embedded (it exists nowhere else). The source is
// read locally whenever settings are selected, to canonicalize against its
// declared types, even when it is not embedded.
let embed = is_local || offline;
let need_source = embed || want_settings;
let mut source_text = None;
if need_source {
match read_source(session, id)? {
SourceRead::Text(text) => source_text = Some(text),View on GitHub (pinned to 61d99ed8e1)