{"record":{"id":"674db0310a28e08a","repo":"unclecode/crawl4ai","slug":"unknown-procedure-c-args-0-r","errorCode":null,"errorMessage":"Unknown procedure {c.args[0]!r}","messagePattern":"Unknown procedure (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"crawl4ai/script/c4ai_script.py","lineNumber":367,"sourceCode":"                p=(self.root/c.args[0]).resolve()\n                if p in seen: raise ValueError(f\"Circular include {p}\")\n                seen.add(p); out+=self._parse_with_includes(p.read_text(),seen)\n            else: out.append(c)\n        return out\n\n    def _collect_procs(self,ir):\n        out=[]\n        for i in ir:\n            if isinstance(i,Proc): self.procs[i.name]=i\n            else: out.append(i)\n        return out\n\n    def _inline_calls(self,ir):\n        out=[]\n        for c in ir:\n            if isinstance(c,Cmd) and c.op==\"CALL\":\n                if c.args[0] not in self.procs:\n                    raise ValueError(f\"Unknown procedure {c.args[0]!r}\")\n                out+=self._inline_calls(self.procs[c.args[0]].body)\n            else: out.append(c)\n        return out\n\n    def _apply_set_vars(self,ir):\n        def sub(s): return re.sub(r\"\\$(\\w+)\",lambda m:str(self.vars.get(m.group(1),m.group(0))) ,s) if isinstance(s,str) else s\n        out=[]\n        for c in ir:\n            if isinstance(c,Cmd):\n                if c.op==\"SETVAR\":\n                    # Store variable\n                    self.vars[c.args[0].lstrip('$')]=c.args[1]\n                else:\n                    # Apply variable substitution to commands that use them\n                    if c.op in(\"TYPE\",\"EVAL\",\"SET\"): c.args=[sub(a) for a in c.args]\n                    out.append(c)\n        return out\n","sourceCodeStart":349,"sourceCodeEnd":385,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/crawl4ai/script/c4ai_script.py#L349-L385","documentation":"ValueError from the C4A-Script compiler's _inline_calls pass: a CALL command references a procedure name that was never defined by a PROC declaration in the compiled source (including its includes). Since procedures are inlined by name lookup in self.procs, an unknown name cannot be resolved.","triggerScenarios":"Writing CALL \"do_thing\" when no PROC do_thing exists, misspelling a procedure name (case-sensitive), or defining the procedure in a file that is not INCLUDEd into the compiled script.","commonSituations":"Renaming a PROC but forgetting call sites, copy-pasting scripts that reference procedures from another file, typos, or case mismatches (DoThing vs dothing).","solutions":["Define the missing PROC in the script or in an included file.","Check spelling and case of the procedure name at both definition and call site.","Ensure the file declaring the procedure is INCLUDEd from the entry script (and not part of an include cycle that failed earlier).","Run validate()/compile_string() in CI to catch unknown procedures before runtime."],"exampleFix":"# before\nCALL \"extract_rows\"   # ValueError: Unknown procedure 'extract_rows'\n\n# after\nPROC extract_pages {\n  EXTRACT css=\"table tr\"\n}\nCALL \"extract_pages\"","handlingStrategy":"validation","validationCode":"import re\n\ndef all_calls_defined(script_text: str) -> list[str]:\n    defined = set(re.findall(r\"PROC\\s+(\\w+)\", script_text))\n    called = set(re.findall(r\"CALL\\s+[\\\"']?(\\w+)[\\\"']?\", script_text))\n    return sorted(called - defined)  # empty list = OK","typeGuard":null,"tryCatchPattern":"try:\n    js = compile_string(script)\nexcept ValueError as e:\n    if 'Unknown procedure' in str(e):\n        undefined = all_calls_defined('\\n'.join(script))\n        raise ValueError(f\"Define or fix: {undefined}\") from e","preventionTips":["Run validate() on every script before deploying or storing it.","Keep PROC names lowercase and consistent; treat them as case-sensitive APIs.","When splitting scripts into files, include the PROC definitions file from every caller."],"tags":["c4a-script","compile","undefined-reference","procedures","validation"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}