{"record":{"id":"06c1216d9a816af4","repo":"cocoindex-io/cocoindex","slug":"could-not-create-spec-for-file-app-path","errorCode":null,"errorMessage":"Could not create spec for file: {app_path}","messagePattern":"Could not create spec for file: (.+?)","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"python/cocoindex/user_app_loader.py","lineNumber":78,"sourceCode":"        app_dir = os.path.dirname(app_path)\n        # Use the file basename as the module name (e.g. main.py -> \"main\"). This\n        # matches the bare-module CLI form (`cocoindex update main`) so memo cache\n        # keys are consistent across both, and avoids triggering the user's\n        # `if __name__ == \"__main__\":` block during module loading.\n        module_name = os.path.splitext(os.path.basename(app_path))[0]\n\n        # If the file lives inside a package (directory has __init__.py),\n        # load it as a proper submodule so that relative imports work.\n        if os.path.isfile(os.path.join(app_dir, \"__init__.py\")):\n            root_parent, package_parts = _find_package_root(app_dir)\n            return _import_as_package_module(root_parent, package_parts, module_name)\n\n        if app_dir not in sys.path:\n            sys.path.insert(0, app_dir)\n        try:\n            spec = importlib.util.spec_from_file_location(module_name, app_path)\n            if spec is None:\n                raise ImportError(f\"Could not create spec for file: {app_path}\")\n            module = importlib.util.module_from_spec(spec)\n            sys.modules[spec.name] = module\n            if spec.loader is None:\n                raise ImportError(f\"Could not create loader for file: {app_path}\")\n            spec.loader.exec_module(module)\n            return module\n        except (ImportError, FileNotFoundError, PermissionError) as e:\n            raise Error(f\"Failed importing file '{app_path}': {e}\") from e\n        finally:\n            if app_dir in sys.path and sys.path[0] == app_dir:\n                sys.path.pop(0)\n\n    # If the target looks like a bare module name (e.g. \"main\") and a\n    # corresponding file exists in the CWD inside a package, load via the\n    # package-qualified name so relative imports work.\n    candidate_file = os.path.join(os.getcwd(), app_target + \".py\")\n    cwd = os.getcwd()\n    if os.path.isfile(candidate_file) and os.path.isfile(","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/user_app_loader.py#L60-L96","documentation":"Raised (as ImportError, then wrapped as `Failed importing file ...`) when `importlib.util.spec_from_file_location` returns None for the given app file. Python could not derive an import spec — typically because the file has an unrecognized extension or the loader machinery cannot handle it.","triggerScenarios":"Calling `cocoindex update <path>` where the path is an existing file but not a loadable Python source file (e.g. missing `.py` extension on a Python file, extension Python cannot map to a loader, or a directory passed in a way that passes the isfile check only for odd filesystems).","commonSituations":"Passing extensionless script files; symlink/permission oddities; files with unusual extensions like `.pyx` or `.pyw` handled differently on some setups; passing a directory path that some shells normalized unexpectedly.","solutions":["Rename the app file to have a `.py` extension (or pass the actual .py file).","Confirm the path is a regular Python source file (`file <path>`, check extension).","Inspect the wrapped `Failed importing file '...': ...` error for the underlying reason."],"exampleFix":"// before\ncocoindex update ./myapp    # extensionless Python file\n// after\nmv myapp myapp.py\ncocoindex update ./myapp.py","handlingStrategy":"validation","validationCode":"assert app_path.endswith(\".py\") and os.path.isfile(app_path), f\"{app_path} is not a Python source file\"","typeGuard":null,"tryCatchPattern":"try:\n    app = cocoindex.user_app_loader.load_user_app(app_target)\nexcept cocoindex.Error as e:\n    if 'Could not create spec' in str(e):\n        print(f'{app_target} is not loadable Python source; rename to .py'); sys.exit(1)\n    raise","preventionTips":["Always target a `.py` file for path-based app loading.","Avoid extensionless scripts or non-Python extensions as the app entry.","Inspect the wrapped cause (`Failed importing file ...`) for the exact importlib reason."],"tags":["python","import","cli","app-loading"],"backgroundTag":"module-init-failed","analyzedSha":"e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b","analyzedAt":"2026-09-08T15:59:19.997Z","contentChangedAt":"2026-09-08T15:59:19.997Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}