{"record":{"id":"2f9e28ca838a80c9","repo":"nodejs/node","slug":"only-relative-paths-are-supported-in-includes","errorCode":null,"errorMessage":"Only relative paths are supported in includes","messagePattern":"Only relative paths are supported in includes","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"deps/inspector_protocol/pdl.py","lineNumber":97,"sourceCode":"      nukeDescription = True\n\n    if len(trimLine) == 0:\n      continue\n\n    match = re.compile(\n        r'^(experimental )?(deprecated )?domain (.*)').match(line)\n    if match:\n      domain = createItem({'domain' : match.group(3)}, match.group(1),\n                          match.group(2))\n      protocol['domains'].append(domain)\n      continue\n\n    match = re.compile(\n        r'^include (.*)').match(line)\n    if match:\n      included_filename = match.group(1)\n      if os.path.isabs(included_filename):\n        raise Exception(\"Only relative paths are supported in includes\")\n      resolved_path = os.path.normpath(os.path.join(os.path.dirname(file_name), included_filename))\n      with open(resolved_path, 'r') as file:\n        included_data = parse(file.read(), resolved_path, map_binary_to_string, source_set)\n        protocol['domains'].extend(included_data['domains'])\n      continue\n\n    match = re.compile(r'^  depends on ([^\\s]+)').match(line)\n    if match:\n      if 'dependencies' not in domain:\n        domain['dependencies'] = []\n      domain['dependencies'].append(match.group(1))\n      continue\n\n    match = re.compile(r'^  (experimental )?(deprecated )?type (.*) '\n                       r'extends (array of )?([^\\s]+)').match(line)\n    if match:\n      if 'types' not in domain:\n        domain['types'] = []","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/inspector_protocol/pdl.py#L79-L115","documentation":"The inspector-protocol PDL parser supports an `include <path>` directive that textually pulls another protocol file into the current one. pdl.py refuses absolute paths so includes stay relocatable and cannot escape the source tree; an absolute include also breaks the os.path.join used to resolve it.","triggerScenarios":"Raised inside parse() when a line matches `^include (.*)` and `os.path.isabs(included_filename)` is true for the captured path.","commonSituations":"Hand-authored or generated .pdl that used a full /home/user/... or C:\\... path in an include line; tooling that emitted absolute paths when stitching protocol fragments; vendored protocol files edited on Windows with drive letters.","solutions":["Rewrite the include directive to use a path relative to the file containing it (e.g. `include ../browser_protocol.pdl`).","Fix the generator/template that emitted the absolute path so it emits repo-relative paths.","Validate .pdl files in CI with a grep for `^include /` to catch regressions."],"exampleFix":"# before\ninclude /home/me/src/js_protocol.pdl\n# after\ninclude js_protocol.pdl","handlingStrategy":"validation","validationCode":"import os\nfor line in open(protocol_file):\n    if line.startswith('include '):\n        path = line[len('include '):].strip()\n        assert not os.path.isabs(path), f'include must be relative: {path}'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Lint .pdl files for `^include /` or drive-letter includes in CI.","Generate protocol fragments from templates that always emit repo-relative paths."],"tags":["inspector-protocol","pdl","path","build","validation"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}