slint-ui/slint · error · std::io::Error
<js error message>
Error message
<js error message>
What it means
This error surfaces a JavaScript promise rejection from a user-supplied file loader callback back into Rust as an std::io::Error. When compile_from_string_with_style encounters an import that the JS `load_callback` must fetch asynchronously, a rejected promise means the file could not be loaded (e.g. network failure, 404, or JS exception). The rejected JsValue's string message becomes the io::Error's message and is propagated to the caller of the Slint WASM compiler API.
Solutions
- Inspect the error message; it is the stringified JS rejection reason — fix the underlying loader failure (wrong URL, 404, CORS).
- Verify the JS file loader always returns a Promise<string> of file contents for every requested path.
- Add try/catch or .catch() around fetch logic in the loader and return a descriptive error message.
- Ensure imported files exist on the server or are embedded/inlined so the loader is never called for missing assets.
Example fix
// before
load: (name) => fetch('/ui/' + name).then(r => r.text())
// after
load: (name) => fetch('/ui/' + name).then(r => {
if (!r.ok) throw new Error(`failed to load ${name}: HTTP ${r.status}`);
return r.text();
}).catch(e => { throw new Error('slint file loader: ' + e.message); }) Defensive patterns
Strategy: try-catch
Validate before calling
// JS: verify the loader resolves every path with a string
const res = await load_callback('App.slint');
if (typeof res !== 'string') throw new Error('loader must return a string'); Type guard
function isLoaderResult(v) { return v instanceof Promise; } Try / catch
try { await instance.compile(source, style); } catch (e) { console.error('slint load failed:', e.message); } Prevention
- Always return Promise<string> from the file loader; wrap non-string results with .then(String).
- Add .catch() to fetch calls to convert network/CORS failures into descriptive messages.
- Pre-check imported file URLs with HEAD requests or a bundled manifest.
When it happens
Trigger: Calling compile_from_string (via the wasm-interpreter API) on .slint source that imports other files, where the registered JS file loader returns a rejected Promise, throws inside the async loader, or resolves to a non-string value (as_string().unwrap_or_default() yields an empty message).
Common situations: Web apps loading .slint files over HTTP with fetch-based loaders that hit 404s, CORS rejections, or offline conditions; loader code throwing TypeErrors; passing a loader that resolves with a Blob/arraybuffer instead of a string.
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
- {e:?}
- {x:?}
- {err}
- Callback ' ' cannot be used with a callback decorator for…
- Callback ' ' cannot be used with a callback decorator for…
AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16).
Data as JSON: /api/errors/3ceaecff1d0cfdd9.
Report an issue: GitHub.
Appendix: source
Thrown at api/wasm-interpreter/src/lib.rs:95
compiler.compiler_configuration(i_slint_core::InternalToken).is_preview = true;
if !style.is_empty() {
compiler.set_style(style)
}
if let Some(load_callback) = optional_import_callback {
let open_import_callback = move |file_name: &Path| -> core::pin::Pin<
Box<dyn core::future::Future<Output = Option<std::io::Result<String>>>>,
> {
Box::pin({
let load_callback = js_sys::Function::from(load_callback.clone());
let file_name: String = file_name.to_string_lossy().into();
async move {
let result = load_callback.call1(&JsValue::UNDEFINED, &file_name.into());
let promise: js_sys::Promise = result.unwrap().into();
let future = wasm_bindgen_futures::JsFuture::from(promise);
match future.await {
Ok(js_ok) => Some(Ok(js_ok.as_string().unwrap_or_default())),
Err(js_err) => Some(Err(std::io::Error::new(
std::io::ErrorKind::Other,
js_err.as_string().unwrap_or_default(),
))),
}
}
})
};
compiler.set_file_loader(open_import_callback);
}
let c = compiler.build_from_source(source, base_url.into()).await;
let line_key = JsValue::from_str("lineNumber");
let column_key = JsValue::from_str("columnNumber");
let message_key = JsValue::from_str("message");
let file_key = JsValue::from_str("fileName");
let level_key = JsValue::from_str("level");
let mut error_as_string = String::new();View on GitHub (pinned to bb937076de)