windmill-labs/windmill · error · Error

preprocessor function is missing

Error message

preprocessor function is missing

What it means

When a script is configured with a preprocessor, the generated Bun wrapper checks that the entrypoint module (Main) exports a `preprocessor` function and that it is callable. If the export is missing or not a function, the wrapper throws 'preprocessor function is missing' at job start, before args are transformed.

Source

Thrown at backend/windmill-worker/src/bun_executor.rs:1881

        };

        let main_import = if codebase.is_some() || has_bundle_cache {
            "./main.js"
        } else {
            "./main.ts"
        };

        let wac_client_import = if has_bundle_cache {
            "./main.js"
        } else {
            "windmill-client"
        };

        let preprocessor = if let Some(pre_args) = pre_args {
            let pre_spread = pre_args.into_iter().map(|x| x.name).join(",");
            format!(
                r#"if (Main.preprocessor === undefined || typeof Main.preprocessor !== 'function') {{
        throw new Error("preprocessor function is missing");
    }}
    function preArgsObjToArr({{ {pre_spread} }}) {{
        return [ {pre_spread} ];
    }}
    args = await Main.preprocessor(...preArgsObjToArr(args));
    const args_json = JSON.stringify(args ?? null, (key, value) => typeof value === 'undefined' ? null : value);
    await fs.writeFile('args.json', args_json, {{ encoding: 'utf8' }})"#
            )
        } else {
            "".to_string()
        };

        let wac_spread = if spread.is_empty() {
            "Object.values(args)".to_string()
        } else {
            format!("argsObjToArr(args)")
        };

View on GitHub (pinned to e474e8803c)

Solutions

  1. Add `export function preprocessor(...) { ... }` (or `export const preprocessor = ...`) to the script's main module.
  2. Ensure the export name is exactly `preprocessor` and it's exported, not just declared.
  3. If no preprocessing is needed, remove the preprocessor args from the script's settings instead.

Example fix

// before
function preprocessor(args) { return transform(args); } // not exported
// after
export async function preprocessor({ name, count }) {
  return [name, count];
}
Defensive patterns

Strategy: validation

Validate before calling

// Before enabling preprocessor args, assert the export exists
if (scriptHasPreprocessorArgs && !/export\s+(async\s+)?function\s+preprocessor|export\s+const\s+preprocessor\s*=/.test(source)) {
  throw new Error('Script declares preprocessor args but does not export a preprocessor function');
}

Try / catch

// The throw happens inside the job; catch when awaiting the job result
try {
  await windmill.runScript(path, hash_, args);
} catch (e) {
  if (e.message.includes('preprocessor function is missing')) {
    console.error('Add: export function preprocessor(...) to the script, or remove preprocessor args');
  }
  throw e;
}

Prevention

When it happens

Trigger: A Windmill script has preprocessor arguments configured (pre_args present), so the worker injects the wrapper, but the script's main module does not define `export function preprocessor(...)` or exports it under a different name / as a non-function.

Common situations: Adding preprocessor args in the UI without adding the preprocessor function to the code, copying code that dropped the export, misspelling `preprocessor`, or defining it as a const arrow function that isn't exported.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/7aa248951b6349a1. Report an issue: GitHub.