Preprocess Error
Trace SER's transform base error and its direct class-member trigger.What this error means and what can trigger it
PreprocessError is the common base for synchronous failures raised while SER lowers component script or markup. It extends RuntimeError with a filename, which lets Vite and other tooling retain source context without having to parse the diagnostic text.
Most failures use a concrete subclass. The base class itself has one production trigger, albeit an unusual one: a class field initializer contains a top-level yield*. For example, class Store { value = yield* LoadValue() } places effect work inside object construction rather than component-level script work.
The detector stops at nested function boundaries. A yield* inside an arrow, method, accessor, or other nested function is not treated as top-level work belonging to the field initializer.
Exactly where it triggers
const bad_member = find_class_member_with_yield_star(stmt);
if (!bad_member) {
return;
}
throw new PreprocessError(
[
`[ASYNC_EFFECT_IN_CLASS_MEMBER]: ${filename}: yield* cannot be used inside class members.`,
`Class fields and methods are not component top-level reactive work. Move the Effect work into a script effect statement before assigning it to the class instance.`,
"",
"Problematic member:",
slice(content, bad_member),
].join("\n"),
filename,
);The compiler raises this synchronously during the Vite/SER transform, before the component module can evaluate and before any effect runtime exists.
For reference, the base class is declared at modules/svelte-effect-runtime/src/errors.ts L55 @ C14.
Why this is the case
SER lowers component-level statements into dispatcher-owned work. A class field follows JavaScript object-construction timing and may run once per instance, long after or long before the component-level statement SER would have generated. Hoisting the expression would change evaluation order and ownership; leaving it in place would put generator syntax into a synchronous initializer.
The compiler rejects the field instead of guessing whether the result should belong to the component, the class instance, or every future instance.