risingwavelabs/risingwave · error

USING must be specified

Error message

USING must be specified

What it means

A WASM UDF must supply its code either via `USING LINK <url>` (fetch wasm binary from a link) or `USING <base64>` (inline binary). `create_wasm` fails when neither option is present, because there is no binary to instantiate a runtime from.

Solutions

  1. Add `USING LINK 'http://.../function.wasm'` to fetch the wasm binary
  2. Or embed the wasm binary as `USING '<base64-encoded wasm>'`
  3. Verify the function is actually a WASM UDF and the DDL template includes a USING clause

Example fix

-- before
CREATE FUNCTION f(BIGINT) RETURNS BIGINT AS wasm;
-- after
CREATE FUNCTION f(BIGINT) RETURNS BIGINT AS wasm USING LINK 'http://udf:8815/f.wasm';
Defensive patterns

Strategy: validation

Validate before calling

if (!sql.includes('USING')) throw new Error('wasm UDF registration requires USING LINK or USING <base64>');

Try / catch

try { await rw.query(createFunctionSql) } catch (e) { if (String(e).includes('USING must be specified')) { /* add USING clause and retry */ } else throw e; }

Prevention

When it happens

Trigger: `CREATE FUNCTION ... AS wasm ...` without any USING clause — `CreateOptions` has neither `using_link` nor `using_base64_decoded`.

Common situations: Omitting USING when registering a WASM UDF; putting the binary path in the wrong option; mixing up rust-UDF (which uses no USING) with wasm-UDF DDL.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/7912abf70b1c6bd0. Report an issue: GitHub.

Appendix: source

Thrown at src/expr/impl/src/udf/wasm.rs:50

    match_fn: |language, _runtime, _link| language == "wasm",
    create_fn: create_wasm,
    build_fn: build,
};

#[linkme::distributed_slice(UDF_IMPLS)]
static RUST: UdfImplDescriptor = UdfImplDescriptor {
    match_fn: |language, _runtime, _link| language == "rust",
    create_fn: create_rust,
    build_fn: build,
};

fn create_wasm(opts: CreateOptions<'_>) -> Result<CreateFunctionOutput> {
    let wasm_binary: Cow<'_, [u8]> = if let Some(link) = opts.using_link {
        read_file_from_link(link)?.into()
    } else if let Some(bytes) = opts.using_base64_decoded {
        bytes.into()
    } else {
        bail!("USING must be specified")
    };

    let runtime = create_wasm_runtime(&wasm_binary)?;
    if runtime.abi_version().0 <= 2 {
        bail!("legacy arrow-udf is no longer supported. please update arrow-udf to 0.3+");
    }

    let name_in_runtime = opts.name.to_owned();
    let convert = UdfArrowConvert {
        legacy: runtime_is_legacy(&runtime),
    };
    let arg_types: Vec<_> = opts
        .arg_types
        .iter()
        .map(|ty| convert.to_arrow_field("", ty))
        .try_collect()?;
    let return_type = convert.to_arrow_field("", opts.return_type)?;
    match opts.kind {

View on GitHub (pinned to 6469eb736d)