ramensoftware/windhawk · warning

the mod's source , so it was not exported

Error message

the mod's source {cause}, so it was not exported

What it means

When exporting a LOCAL mod whose source file cannot be read (SourceRead::Unusable), the mod cannot be embedded anywhere, so export_mod skips it entirely and emits this warning: 'the mod's source <cause>, so it was not exported'. The cause explains how the read failed.

Solutions

  1. Restore or fix the local mod's source file on disk, then re-export
  2. Recreate the local mod (paste its source) so the file exists again
  3. Exclude the broken local mod from the export selection
  4. Check file permissions on the Windhawk mods directory

Example fix

null
Defensive patterns

Strategy: validation

Validate before calling

// before export: verify local mod source files exist and are readable
for id in local_mod_ids_in_selection() {
    let p = local_mod_source_path(id);
    if !p.exists() || std::fs::read(&p).is_err() { eprintln!("{id}: source unreadable"); }
}

Type guard

fn source_readable(p: &Path) -> bool {
    p.is_file() && std::fs::File::open(p).is_ok()
}

Prevention

When it happens

Trigger: Running `data export` with a local (@-prefixed) mod selected whose source file is missing, unreadable, or fails validation — the mod is dropped from the archive.

Common situations: Users deleting or renaming a local mod's .whcpp/compilation file after install; permission problems on the mods storage directory; migrating machines without copying mod source files.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of ramensoftware/windhawk@61d99ed8e1 (2026-09-12). Data as JSON: /api/errors/5975ca68d9246f3b. Report an issue: GitHub.

Appendix: source

Thrown at src/windhawk-core/core/src/services/user_data.rs:214

        ));
        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),
            SourceRead::Unusable(cause) => {
                if is_local {
                    warnings.push(warn(
                        id,
                        format!("the mod's source {cause}, so it was not exported"),
                    ));
                    return Ok(None);
                }
                // A repository mod with no usable source (a broken install):
                // export it reference-only, without settings.
                let mut message =
                    format!("the mod source {cause}, so its settings were not exported");
                if offline {
                    message.push_str(
                        "; this offline archive references the mod instead of embedding it",
                    );
                }
                warnings.push(warn(id, message));
            }
        }
    }

View on GitHub (pinned to 61d99ed8e1)