{"record":{"id":"bc44043d20f17584","repo":"apache/beam","slug":"file-path-is-not-a-valid-js-file","errorCode":null,"errorMessage":"File \"{path}\" is not a valid .js file.","messagePattern":"File \"(.+?)\" is not a valid \\.js file\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/yaml_mapping.py","lineNumber":276,"sourceCode":"        \"quickjs-ng library is not installed.\")\n\n  if expression:\n    source_code = f\"\"\"\n    function udf(__row__) {{\n      with (__row__) {{\n        return ({expression});\n      }}\n    }}\n    \"\"\"\n    user_entrypoint = 'udf'\n\n  elif callable:\n    source_code = f\"var __udf__ = ({callable});\"\n    user_entrypoint = '__udf__'\n\n  else:\n    if not path.endswith('.js'):\n      raise ValueError(f'File \"{path}\" is not a valid .js file.')\n    udf_code = FileSystems.open(path).read().decode()\n    source_code = udf_code\n    user_entrypoint = name\n\n  source_code += f\"\"\"\n  function __convert_dates__(obj) {{\n    if (obj && typeof obj === 'object') {{\n      if (obj.__date__) {{\n        return new Date(obj.value);\n      }}\n      for (var key in obj) {{\n        if (obj.hasOwnProperty(key)) {{\n          obj[key] = __convert_dates__(obj[key]);\n        }}\n      }}\n    }}\n    return obj;\n  }}","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/yaml_mapping.py#L258-L294","documentation":"The Beam YAML MapToFields transform raises this when a JavaScript UDF is specified via `path` but the file name does not end with '.js'. When neither `expression` nor `callable` is given, the transform loads the UDF from a file, and it only accepts files with a .js extension as a sanity check before reading them via FileSystems.","triggerScenarios":"Calling _expand_javascript_mapping_func (via MapToFields with language: javascript) with config {'path': '...', 'name': '...'} where path lacks a .js suffix, e.g. a .ts file, extensionless file, or a directory path.","commonSituations":"Users point `path` at a TypeScript file, a bundled/minified file with a different extension, a file with wrong casing (.JS handled only if endswith matches exactly — '.JS' fails), or accidentally pass a directory or URL instead of a .js file.","solutions":["Rename or point to the file so the path ends with '.js'.","If the code is TypeScript or needs bundling, compile/transpile it to plain JavaScript first and reference the .js output.","Alternatively inline the function via the `callable` or `expression` config option instead of `path`."],"exampleFix":"# before\nconfig:\n  language: javascript\n  path: my_udf.ts\n  name: udf\n# after\nconfig:\n  language: javascript\n  path: my_udf.js\n  name: udf","handlingStrategy":"validation","validationCode":"import os\nassert path.endswith('.js'), f'File \"{path}\" is not a valid .js file.'\nassert os.path.isfile(path.replace('gs://', '')) or path.startswith('gs://')","typeGuard":"def is_js_udf_spec(cfg: dict) -> bool:\n    return isinstance(cfg.get('path'), str) and cfg['path'].endswith('.js')","tryCatchPattern":"try:\n    result = expand(cfg)\nexcept ValueError as e:\n    if 'is not a valid .js file' in str(e):\n        cfg['path'] = fix_extension(cfg['path'], '.js')\n        result = expand(cfg)\n    else:\n        raise","preventionTips":["Always use .js extension for JavaScript UDF files","Transpile TypeScript before referencing it in YAML config","Prefer inline `expression`/`callable` for short UDFs"],"tags":["yaml","beam-yaml","javascript","file-extension","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}