windmill-labs/windmill · error

clock is not supported

Error message

clock is not supported

What it means

The windmill-parser-r WASM libc shim stubs clock() (from time.h) with a panic — the WASM sandbox intentionally provides no time source to the compiled C parser. If the tree-sitter C runtime or a custom scanner calls clock() (usually for profiling, timeouts, or debugging instrumentation), the shim panics with "clock is not supported" and the parse fails.

Source

Thrown at backend/parsers/windmill-parser-r/src/wasm_libc.rs:222

    }
    0 // Return false (0)
}

#[no_mangle]
pub extern "C" fn iswlower(wc: wint_t) -> c_int {
    // Check if the character is a lowercase letter ('a' to 'z')
    if wc >= 'a' as wint_t && wc <= 'z' as wint_t {
        return 1; // Return true (1)
    }
    0 // Return false (0)
}
// End of AI implemetation

/* --------------------------------- time.h --------------------------------- */

#[no_mangle]
pub unsafe extern "C" fn clock() -> u64 {
    panic!("clock is not supported");
}

/* --------------------------------- ctype.h -------------------------------- */

#[no_mangle]
pub unsafe extern "C" fn isprint(c: c_int) -> bool {
    c >= 32 && c <= 126
}

/* --------------------------------- stdio.h -------------------------------- */

#[no_mangle]
pub unsafe extern "C" fn fprintf(_file: *mut c_void, _format: *const c_void, _args: ...) -> c_int {
    panic!("fprintf is not supported");
}

#[no_mangle]
pub unsafe extern "C" fn fputs(_s: *const c_void, _file: *mut c_void) -> c_int {

View on GitHub (pinned to e474e8803c)

Solutions

  1. Rebuild the grammar/scanner without profiling or debug instrumentation (disable TREE_SITTER_DEBUG or equivalent) so clock() is never called.
  2. Implement clock() in the shim to return a monotonically increasing counter (e.g. a static AtomicU64 of elapsed ticks) instead of panicking, if the value is only used for measurement.
  3. Patch scanner.c to remove or compile-out the clock() usage for WASM builds (#ifdef TREE_SITTER_WASM).
  4. Report the grammar upstream so the WASM build drops the timing code.

Example fix

// before (wasm_libc.rs)
#[no_mangle]
pub unsafe extern "C" fn clock() -> u64 {
    panic!("clock is not supported");
}

// after — harmless monotonic counter
static CLOCK_TICKS: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);

#[no_mangle]
pub unsafe extern "C" fn clock() -> u64 {
    CLOCK_TICKS.fetch_add(1, std::sync::atomic::Ordering::Relaxed)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Cannot pre-detect the C call, but ensure the grammar build has no profiling:
// at build time, verify the generated C/scanner does not reference clock():
//   grep -n '\bclock\s*(' scanner.c src/parser.c  # must return nothing for WASM builds

Try / catch

try {
  return parser.parse(doc);
} catch (e) {
  if (String(e).includes('clock is not supported')) {
    // rebuild the grammar without profiling/debug instrumentation and retry once
    return null; // or trigger the rebuild pipeline
  }
  throw e;
}

Prevention

When it happens

Trigger: The compiled C code calls clock(): a custom scanner.c containing timing/debug instrumentation guarded only by a runtime (not compile-time) flag, or a tree-sitter runtime build with profiling enabled (e.g. TREE_SITTER_DEBUG) that measures parse time via clock().

Common situations: A grammar build that left debug/profiling instrumentation compiled in; a scanner authored for native tree-sitter (where clock() exists) reused in the WASM build; a grammar upgrade that introduced timing code.

Related errors


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