{"record":{"id":"3433e76d4d88c82b","repo":"cube-js/cube","slug":"no-deployable-files-found-in","errorCode":null,"errorMessage":"no deployable files found in {}","messagePattern":"no deployable files found in (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust/cube-cli/src/commands/deploy.rs","lineNumber":81,"sourceCode":"\nfn sha1_hex(data: &[u8]) -> String {\n    let mut hasher = Sha1::new();\n    hasher.update(data);\n    format!(\"{:x}\", hasher.finalize())\n}\n\npub async fn command(args: Args, ctx: &Ctx) -> Result<()> {\n    let api = ctx.api()?;\n    let deployment = args.deployment;\n    let base = format!(\"/build/api/v1/deployments/{deployment}/data-model\");\n\n    if !args.directory.is_dir() {\n        bail!(\"{} is not a directory\", args.directory.display());\n    }\n    let mut files = Vec::new();\n    collect_files(&args.directory, &args.directory, &mut files)?;\n    if files.is_empty() {\n        bail!(\"no deployable files found in {}\", args.directory.display());\n    }\n    files.sort();\n\n    // Hash local files and diff against the server's content hashes.\n    let mut query = Vec::new();\n    util::push(&mut query, \"branchName\", &args.branch);\n    let upstream = api.get(&format!(\"{base}/file-hashes\"), &query).await?;\n    let upstream = upstream.get(\"files\").cloned().unwrap_or(upstream);\n\n    let mut manifest = serde_json::Map::new();\n    let mut to_upload = Vec::new();\n    for (rel, path) in &files {\n        let data =\n            std::fs::read(path).with_context(|| format!(\"failed to read {}\", path.display()))?;\n        let hash = sha1_hex(&data);\n        let unchanged = upstream\n            .get(rel)\n            .and_then(|f| f.get(\"hash\"))","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/rust/cube-cli/src/commands/deploy.rs#L63-L99","documentation":"Raised by `cube deploy` after path validation: the directory exists, but walking it (collect_files) found zero deployable files matching the expected data-model patterns. The CLI refuses an empty upload rather than wiping or no-oping the deployment's data model.","triggerScenarios":"`cube deploy <deployment> --directory <dir>` where the directory contains none of the recognized deployable files (e.g. no .js/.yml Cube schema files): wrong directory, all files excluded by ignore rules, or an empty scaffolded folder.","commonSituations":"Pointing at the repo root when schemas live under a subfolder; a .gitignore-like exclusion matching everything; freshly initialized project with no schema files yet; CI checkout that skipped the schema folder (sparse checkout, wrong path filter).","solutions":["Point --directory at the folder that actually contains your Cube data-model files.","List the folder contents and confirm schema files (e.g. model .js/.cube/.yml files) are present.","Check any include/exclude patterns or ignore rules that might be filtering every file.","Fix the CI checkout so schema files land in the directory before deploying."],"exampleFix":"// before\ncube deploy 42 --directory .            # repo root has no model files\n// after\ncube deploy 42 --directory ./cube/schema","handlingStrategy":"validation","validationCode":"let count = std::fs::read_dir(&dir)?.filter(|e| {\n    e.as_ref().ok().map_or(false, |e| {\n        let n = e.file_name().to_string_lossy().into_owned();\n        n.ends_with(\".js\") || n.ends_with(\".yml\") || n.ends_with(\".cube\")\n    })\n}).count();\nif count == 0 { anyhow::bail!(\"no model files in {}\", dir.display()); }","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"no deployable files found\") => {\n        // fail the pipeline early with a pointer to the correct schema folder\n    }\n    other => other?,\n}","preventionTips":["Verify the schema folder contains model files before deploying (add a CI check).","Review ignore/exclude patterns so they can't filter out everything.","Pin --directory to the canonical schema path per repo, not the repo root.","Check CI checkout filters (sparse checkout, path filters) include the schema directory."],"tags":["cli","validation","filesystem","empty-input"],"backgroundTag":"empty-deploy-artifact","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}