sinelaw/fresh · error
Semantic errors
Error message
Semantic errors: {} What it means
After parsing succeeds, `transpile_typescript` runs oxc's semantic analysis; any semantic-level errors reported by SemanticBuilder abort the transpile with this message. The source parsed but failed symbol/scoping analysis needed by the transformer.
Solutions
- Fix each reported semantic error in the source (message lists them joined by '; ').
- Refactor the offending construct (e.g. move `super` usage into a class method).
- If it looks like a false positive, check the oxc version in Cargo.lock and update/downgrade accordingly.
Defensive patterns
Strategy: try-catch
Try / catch
if let Err(e) = transpile_typescript(src, "plugin.ts") {
if e.to_string().starts_with("Semantic errors") { log::error!("semantic analysis failed: {e}"); }
} Prevention
- Keep plugin TypeScript to standard, well-formed constructs.
- Pin/update oxc versions deliberately and re-run plugin build tests on bumps.
- Include a transpile smoke test for every shipped plugin.
When it happens
Trigger: Calling `transpile_typescript` on source that parses but produces semantic errors — rare, typically constructs the analyzer rejects (e.g. `super` outside a class, invalid binding forms).
Common situations: Hand-edited plugin sources with structurally odd code; generated code fed to the transpiler; oxc version differences flagging constructs previously tolerated.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- TypeScript parse errors
- Transform errors
- isolated-declarations parse errors in
- workspace is still being created and cannot be
- no such folder
AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13).
Data as JSON: /api/errors/ec5b68f317986bff.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fresh-parser-js/src/lib.rs:37
pub fn transpile_typescript(source: &str, filename: &str) -> Result<String> {
let allocator = Allocator::default();
let source_type = SourceType::from_path(filename).unwrap_or_default();
// Parse
let parser_ret = Parser::new(&allocator, source, source_type).parse();
if !parser_ret.errors.is_empty() {
let errors: Vec<String> = parser_ret.errors.iter().map(|e| e.to_string()).collect();
return Err(anyhow!("TypeScript parse errors: {}", errors.join("; ")));
}
let mut program = parser_ret.program;
// Semantic analysis (required for transformer)
let semantic_ret = SemanticBuilder::new().build(&program);
if !semantic_ret.errors.is_empty() {
let errors: Vec<String> = semantic_ret.errors.iter().map(|e| e.to_string()).collect();
return Err(anyhow!("Semantic errors: {}", errors.join("; ")));
}
// Get scoping info for transformer
let scoping = semantic_ret.semantic.into_scoping();
// Transform (strip TypeScript types)
let transform_options = TransformOptions::default();
let transformer_ret = Transformer::new(&allocator, Path::new(filename), &transform_options)
.build_with_scoping(scoping, &mut program);
if !transformer_ret.errors.is_empty() {
let errors: Vec<String> = transformer_ret
.errors
.iter()
.map(|e| e.to_string())
.collect();
return Err(anyhow!("Transform errors: {}", errors.join("; ")));
}View on GitHub (pinned to 67894ca546)