Skip to content

Commit 60b83bc

Browse files
fix(build): fail codegen clearly on a non-UTF-8 support file
generate_skill_bundle embeds every plugin/skills file via include_str!, which only accepts UTF-8. A binary support file (e.g. assets/*.png) would otherwise fail to compile with an opaque "stream did not contain valid UTF-8" error pointing at the generated file. Guard it with a clear panic naming the offending file and stating binary support files aren't embeddable yet. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 2b9ff03 commit 60b83bc

1 file changed

Lines changed: 26 additions & 0 deletions

File tree

build.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,17 @@ fn collect_files_relative(root: &Path) -> Vec<String> {
339339
files
340340
}
341341

342+
/// True when `path` is a readable UTF-8 text file. Used to fail the skill
343+
/// bundle codegen early with a clear message when a binary support file would
344+
/// otherwise break `include_str!` with an opaque compile error.
345+
fn is_probably_utf8_text(path: &Path) -> bool {
346+
match fs::read(path) {
347+
Ok(bytes) => std::str::from_utf8(&bytes).is_ok(),
348+
// Unreadable files fall through to include_str!'s own error.
349+
Err(_) => true,
350+
}
351+
}
352+
342353
/// Generates `$OUT_DIR/plugin_bundle_generated.rs`: a recursive manifest of
343354
/// every file under `plugin/skills/` (SKILL.md *and* any `references/`,
344355
/// `scripts/`, `assets/` support files), embedded via `include_str!` at compile
@@ -367,6 +378,21 @@ fn generate_skill_bundle() {
367378
// rerun on each individual file so edits re-trigger codegen even if the
368379
// directory mtime does not change.
369380
println!("cargo::rerun-if-changed=plugin/skills/{relative}");
381+
// Every embedded file goes through `include_str!`, which only accepts
382+
// UTF-8. A binary support file (e.g. `assets/*.png`) would otherwise
383+
// fail to compile with an opaque "stream did not contain valid UTF-8"
384+
// error pointing at the generated file, not the offending asset. Guard
385+
// it here with a clear message; binary support files are not embeddable
386+
// yet (add `include_bytes!` handling when that becomes a requirement).
387+
let abs = skills_root.join(&relative);
388+
if !is_probably_utf8_text(&abs) {
389+
panic!(
390+
"plugin/skills/{relative} is not a UTF-8 text file. The skill bundle codegen \
391+
embeds every file via include_str!, so binary support files (e.g. images) are \
392+
not embeddable yet. Remove the binary file or add include_bytes! support to \
393+
build.rs (generate_skill_bundle)."
394+
);
395+
}
370396
let deploy = format!("skills/{relative}");
371397
let source = format!("skills/{relative}");
372398
code.push_str(&format!(

0 commit comments

Comments
 (0)