unclecode/crawl4ai · error · ValueError
Unknown procedure {cmd.args[0]!r}
Error message
Unknown procedure {cmd.args[0]!r} What it means
ValueError from the JS-emission stage (_handle_cmd_or_proc) of the C4A-Script compiler: it encounters a CALL to a procedure absent from self.procs while emitting JavaScript. This duplicates the earlier _inline_calls check as a defensive guard at emit time.
Source
Thrown at crawl4ai/script/c4ai_script.py:612
if cond_type == "EXISTS":
return f"!!document.querySelector('{condition[1]}')"
elif cond_type == "NOT":
# Recursively handle the negated condition
inner_condition = self._emit_condition(condition[1])
return f"!({inner_condition})"
else: # JS condition
return condition[1]
def _handle_cmd_or_proc(self, cmd):
"""Handle a command that might be a regular command or a procedure call"""
if not cmd:
return ""
if isinstance(cmd, Cmd):
if cmd.op == "CALL":
# Inline the procedure
if cmd.args[0] not in self.procs:
raise ValueError(f"Unknown procedure {cmd.args[0]!r}")
proc_body = self.procs[cmd.args[0]].body
return "\n".join([self._emit_js(c) for c in proc_body if c.op != "NOP"])
else:
return self._emit_js(cmd)
return ""
# --------------------------------------------------------------------------- #
# 5. Helpers + demo
# --------------------------------------------------------------------------- #
def compile_string(script: Union[str, List[str]], *, root: Union[pathlib.Path, None] = None) -> List[str]:
"""Compile C4A-Script from string or list of strings to JavaScript.
Args:
script: C4A-Script as a string or list of command strings
root: Root directory for resolving includes (optional)
Returns:View on GitHub (pinned to 7e80152142)
Solutions
- If writing scripts normally, fix the root cause as for any unknown procedure: define the PROC or correct its name.
- Prefer the public compile_string()/compile() entry points instead of driving internal passes yourself.
- If manipulating IR programmatically, run _collect_procs before _inline_calls/emit so every PROC is registered.
- Ensure includes carrying PROC definitions are present in the parsed source.
Example fix
# before
js = compile_string(["CALL 'do_thing'"]) # ValueError: Unknown procedure 'do_thing'
# after
js = compile_string([
"PROC do_thing {",
" CLICK 'button#go'",
"}",
"CALL 'do_thing'",
]) Defensive patterns
Strategy: validation
Try / catch
try:
js_lines = compile_string(script_lines, root=root)
except ValueError as e:
if 'Unknown procedure' in str(e):
# define the PROC or fix its name, then recompile
raise Prevention
- Use public entry points (compile_string/compile) rather than internal passes.
- If building IR programmatically, register procedures before inlining/emitting.
- Keep scripts in CI-validated form so emit-time surprises can't reach production.
When it happens
Trigger: Normally unreachable because _inline_calls already resolves or rejects every CALL — but can fire when the IR is manipulated between passes, when a Proc is added after collection, or when using the emitter on hand-constructed command lists.
Common situations: Programmatic use of compiler internals (building Cmd lists manually), version skew between cached/partial IR and the emitter, or subclass overrides that reorder passes.
Related errors
- Unknown procedure {c.args[0]!r}
- LLM returned empty script.
- Circular include {p}
- C4A Script compilation error (script {i+1}): Line {error.l
- C4A script compiler not available. Please ensure crawl4ai.sc
AI-assisted analysis of unclecode/crawl4ai@7e80152142 (2026-08-14).
Data as JSON: /api/errors/755f0c41f6350b9b.
Report an issue: GitHub.