the-benchmarker/web-frameworks · critical
Failed to parse app.zl
Error message
Failed to parse app.zl
What it means
zeno-rs-axum's main loads app.zl (from disk with a compile-time include_str! fallback) and parses it via parse_string; on a syntax error the .expect panics with "Failed to parse app.zl", preventing the Matchit router from being built and the axum server from starting.
Solutions
- Feed app.zl to the parser or CLI to get the exact syntax error location and fix the DSL
- Use git diff on app.zl to find unintended edits or unresolved merge conflict markers
- Remove or repair an invalid app.zl in the working directory so it does not shadow the compile-time fallback
- Align app.zl with the DSL grammar of the installed engine version after upgrades
- Swap expect for explicit error handling that logs the parse diagnostic, making future failures debuggable
Example fix
// before
let main_node = parse_string(&zl_content, "app.zl").expect("Failed to parse app.zl");
// after
let main_node = match parse_string(&zl_content, "app.zl") {
Ok(node) => node,
Err(e) => {
eprintln!("app.zl parse error: {e}");
std::process::exit(1);
}
}; Defensive patterns
Strategy: validation
Validate before calling
// preflight: parse app.zl before booting axum
let zl_content = std::fs::read_to_string("app.zl")
.unwrap_or_else(|_| include_str!("../app.zl").to_string());
if let Err(e) = zeno::parse_string(&zl_content, "app.zl") {
eprintln!("app.zl failed to parse; server not started: {e:?}");
std::process::exit(1);
} Type guard
null
Try / catch
// catch the parse failure instead of expect-panicking
let main_node = parse_string(&zl_content, "app.zl")
.map_err(|e| { eprintln!("app.zl parse error: {e:?}"); std::process::exit(1); })
.unwrap(); Prevention
- Run parse validation of app.zl in CI on every change
- Diff-review app.zl edits like any other source file
- Ensure no stale, malformed app.zl exists in the deployment working directory
- Re-check app.zl compatibility whenever the zeno engine crate is upgraded
- Add an entrypoint script that syntax-checks app.zl before exec'ing the server
When it happens
Trigger: Starting the axum server when the app.zl found in the working directory (or the bundled ../app.zl fallback) is not valid Zeno DSL — parse_string returns Err and expect panics during main's initialization phase.
Common situations: Manual edit of app.zl introduced a typo; partial merge left malformed route definitions; a broken app.zl in the runtime working directory overrides the valid baked-in copy; engine/DSL version upgrade changed the accepted grammar.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
AI-assisted analysis of the-benchmarker/web-frameworks@3795a31d72 (2026-09-15).
Data as JSON: /api/errors/eb2199c861ab5b68.
Report an issue: GitHub.
Appendix: source
Thrown at rust/zeno-rs-axum/src/main.rs:141
engine.register(
"http.post",
Arc::new(move |_, _, node, _| {
let raw = node.value.clone().unwrap_or_default().trim().to_string();
let clean = if raw.starts_with('\'') || raw.starts_with('"') {
raw[1..raw.len() - 1].to_string()
} else {
raw
};
r_post.lock().unwrap().push(("POST".to_string(), clean, node.clone()));
Ok(())
}),
empty_slot_meta(),
);
// Load & Parse app.zl (with compile-time fallback for container runtime)
let zl_content = std::fs::read_to_string("app.zl")
.unwrap_or_else(|_| include_str!("../app.zl").to_string());
let main_node = parse_string(&zl_content, "app.zl").expect("Failed to parse app.zl");
let parent_scope = Scope::new(None);
let mut init_ctx = Context::new();
let _ = engine.execute(&mut init_ctx, &main_node, &parent_scope);
// Build Matchit Router
let mut route_map: HashMap<String, MethodHandler> = HashMap::new();
for (method, path, node) in routes.lock().unwrap().drain(..) {
let matchit_path = convert_path_to_matchit(&path);
println!("Registered route: {} {} -> matchit: {}", method, path, matchit_path);
let entry = route_map
.entry(matchit_path)
.or_insert(MethodHandler { get: None, post: None });
if method == "GET" {
entry.get = Some(node);
} else if method == "POST" {
entry.post = Some(node);
}View on GitHub (pinned to 3795a31d72)