{"record":{"id":"1e1511113ec2c982","repo":"crewAIInc/crewAI","slug":"no-deployable-project-files-were-found","errorCode":null,"errorMessage":"No deployable project files were found.","messagePattern":"No deployable project files were found\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/cli/src/crewai_cli/deploy/archive.py","lineNumber":49,"sourceCode":"    \".env.sample\",\n}\n_EXCLUDED_SUFFIXES = {\n    \".pyc\",\n    \".pyo\",\n}\n\n\ndef create_project_zip(\n    project_name: str,\n    *,\n    project_dir: Path | None = None,\n    repository: git.Repository | None = None,\n) -> Path:\n    \"\"\"Create a deployable ZIP archive for a CrewAI project.\"\"\"\n    root = (project_dir or Path.cwd()).resolve()\n    files = _project_files(root, repository)\n    if not files:\n        raise ValueError(\"No deployable project files were found.\")\n\n    staged_root = _stage_project(root, files)\n    archive_handle = tempfile.NamedTemporaryFile(\n        prefix=f\"{project_name}-\",\n        suffix=\".zip\",\n        delete=False,\n    )\n    archive_path = Path(archive_handle.name)\n    archive_handle.close()\n\n    try:\n        with zipfile.ZipFile(archive_path, \"w\", zipfile.ZIP_DEFLATED) as zip_file:\n            for relative_path in _walk_files(staged_root):\n                absolute_path = staged_root / relative_path\n                zip_file.write(absolute_path, relative_path.as_posix())\n    finally:\n        shutil.rmtree(staged_root, ignore_errors=True)\n","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/cli/src/crewai_cli/deploy/archive.py#L31-L67","documentation":"Raised by _check_index_exists when scoped_index is false but self.cluster is None. The cluster-level branch needs the cluster handle to call cluster.search_indexes().get_all_indexes(); if the tool was constructed without a cluster connection (e.g. only cluster_string or neither), that handle is missing and the guard fires before any API call.","triggerScenarios":"Constructing the tool with scoped_index=False while passing no cluster instance (relying on connection string/credentials that never produced a connected cluster object).","commonSituations":"Mixing the two init modes — passing cluster_string + credentials (scoped-style config) but setting scoped_index=False, which expects an already-connected Cluster object.","solutions":["Connect first and pass the cluster: cluster = Cluster('couchbase://localhost', authenticator=PasswordAuthenticator(user, pw)); tool = CouchbaseFTSVectorSearchTool(cluster=cluster, ..., scoped_index=False).","Or keep scoped_index=True when you are using connection-string/credential configuration.","Ensure cluster.wait_until_ready(...) completed so the handle is usable."],"exampleFix":"# before\ntool = CouchbaseFTSVectorSearchTool(bucket_name='travel', scope_name='inventory', collection_name='hotel', index_name='idx', scoped_index=False)  # ValueError: Cluster instance must be provided\n# after\nfrom couchbase.cluster import Cluster\nfrom couchbase.auth import PasswordAuthenticator\ncluster = Cluster('couchbase://127.0.0.1', authenticator=PasswordAuthenticator('admin', 'pass'))\ntool = CouchbaseFTSVectorSearchTool(cluster=cluster, bucket_name='travel', scope_name='inventory', collection_name='hotel', index_name='idx', scoped_index=False)","handlingStrategy":"type-guard","validationCode":"if not scoped_index and cluster is None:\n    raise ValueError(\"scoped_index=False requires a connected cluster instance\")\ntool = CouchbaseFTSVectorSearchTool(cluster=cluster, scoped_index=scoped_index, ...)","typeGuard":"from couchbase.cluster import Cluster\n\ndef has_cluster(conn: object) -> bool:\n    \"\"\"True when conn is a usable connected Couchbase Cluster.\"\"\"\n    return isinstance(conn, Cluster) and conn is not None","tryCatchPattern":null,"preventionTips":["Decide the init mode up front: cluster instance + scoped_index=False, or connection string + scoped_index=True.","Call cluster.wait_until_ready(...) before passing the handle.","Wrap tool construction in a factory that rejects mismatched configurations early."],"tags":["couchbase","configuration","validation","cluster"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}