windmill-labs/windmill · error · Error

result.substring(__RESULT_ERR_PREFIX.length)

Error message

result.substring(__RESULT_ERR_PREFIX.length)

What it means

For parameters typed as sanitized enums (string with allowed variants, SANITIZED_ENUM_STR), Windmill interpolates the argument into the SQL query only if the supplied runtime value is a string. If the argument is missing or not a JSON string, this error names the parameter.

Source

Thrown at backend/windmill-jseval/src/lib.rs:774

                let client = state_for_user_state.client.clone();
                let job_id = root_flow_job_id_for_state.clone();
                async move {
                    const ERR_PREFIX: &str = "\x00__WINDMILL_ERR__\x00";
                    match client.get_flow_user_state(&job_id, &key).await {
                        Ok(value) => {
                            serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string())
                        }
                        Err(e) => format!("{}{}", ERR_PREFIX, e),
                    }
                }
            }))),
        )?;

        let wrapper_code = r#"
            const __RESULT_ERR_PREFIX = '\x00__WINDMILL_ERR__\x00';
            function __throwOrParse(result) {
                if (typeof result === 'string' && result.startsWith(__RESULT_ERR_PREFIX)) {
                    throw new Error(result.substring(__RESULT_ERR_PREFIX.length));
                }
                return JSON.parse(result);
            }

            async function __getResult(stepId) {
                return __throwOrParse(await __fetchResult(stepId));
            }

            async function flow_user_state(key) {
                return __throwOrParse(await __fetchFlowUserState(key));
            }
        "#;
        ctx.eval::<(), _>(wrapper_code)
            .catch(ctx)
            .map_err(quickjs_error_to_anyhow)?;
    } else {
        let stub_code = r#"
            function __getResult(stepId) {

View on GitHub (pinned to e474e8803c)

Solutions

  1. Pass the parameter as a plain JSON string whose value is one of the enum's allowed variants
  2. Convert numbers/other types to strings at the caller (e.g. String(value) or .toString()) before invoking the script
  3. Provide a default string value for the parameter in the script signature
  4. Check flow step input mappings and app form components so they emit strings, not raw typed values

Example fix

// before (caller passes a number)
await wmill.runScript(..., { status: 2 })
// after
await wmill.runScript(..., { status: 'active' })
Defensive patterns

Strategy: type-guard

Validate before calling

function validateEnumArgs(args, signature) {
  for (const p of signature.filter(p => p.type === 'enum')) {
    const v = args[p.name];
    if (typeof v !== 'string') throw new Error(`enum param '${p.name}' must be a string, got ${v === null ? 'null' : typeof v}`);
    if (p.variants && !p.variants.includes(v)) throw new Error(`'${v}' not in [${p.variants}]`);
  }
}
validateEnumArgs({ status: 'active' }, [{ name: 'status', type: 'enum', variants: ['active','inactive'] }]);

Type guard

const isEnumStr = (v, variants) => typeof v === 'string' && (!variants || variants.includes(v));

Try / catch

try {
  await runSqlScript(path, { status: value });
} catch (e) {
  if (/needs to receive a string/.test(e.message)) {
    const name = e.message.match(/`(.+)`/)?.[1];
    throw new Error(`Pass '${name}' as a string matching the enum variants, got ${typeof value}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling a postgresql/mysql/mssql/duckdb/bigquery/oracledb script whose signature has an enum (Str with variants) parameter, while passing a non-string JSON value (number, null, object, bool) or omitting the argument entirely.

Common situations: Passing an integer or null for an enum-typed path/query param from a flow step; frontend/app form sending raw JSON where the caller assumed coercion; API calls with missing payload keys; workflow variables bound to the wrong type.

Related errors


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