{"record":{"id":"67a57583b3d4cb76","repo":"affaan-m/ECC","slug":"pr-title-cannot-be-empty","errorCode":null,"errorMessage":"PR title cannot be empty","messagePattern":"PR title cannot be empty","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"ecc2/src/worktree/mod.rs","lineNumber":542,"sourceCode":"    };\n\n    Ok(Some(format!(\n        \"{repo_url}/compare/{}...{}?expand=1\",\n        percent_encode_git_ref(&worktree.base_branch),\n        percent_encode_git_ref(&worktree.branch)\n    )))\n}\n\nfn create_draft_pr_with_gh(\n    worktree: &WorktreeInfo,\n    title: &str,\n    body: &str,\n    options: &DraftPrOptions,\n    gh_bin: &Path,\n) -> Result<String> {\n    let title = title.trim();\n    if title.is_empty() {\n        anyhow::bail!(\"PR title cannot be empty\");\n    }\n\n    let base_branch = options\n        .base_branch\n        .as_deref()\n        .map(str::trim)\n        .filter(|value| !value.is_empty())\n        .unwrap_or(&worktree.base_branch);\n\n    let push = Command::new(\"git\")\n        .arg(\"-C\")\n        .arg(&worktree.path)\n        .args([\"push\", \"-u\", \"origin\", &worktree.branch])\n        .output()\n        .context(\"Failed to push worktree branch before PR creation\")?;\n    if !push.status.success() {\n        let stderr = String::from_utf8_lossy(&push.stderr);\n        anyhow::bail!(\"git push failed: {stderr}\");","sourceCodeStart":524,"sourceCodeEnd":560,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/ecc2/src/worktree/mod.rs#L524-L560","documentation":"create_draft_pr_with_gh trims the supplied title and bails if empty before pushing or invoking gh. An empty PR title is rejected by GitHub anyway, so the library fails fast with a clearer message than the gh CLI would produce.","triggerScenarios":"Calling create_draft_pr / create_draft_pr_with_options with `\"\"`, whitespace-only, or a title that a sanitizer reduced to empty.","commonSituations":"PR form submitted with no title; title field derived from commit subject that was empty; trimming layer removed template markers leaving nothing.","solutions":["Validate the title in the calling layer (`title.trim().is_empty()`) and block submission.","Default the title to the latest commit subject when the user provides none.","Ensure the title input has a required-field check in the UI."],"exampleFix":"// before\nlet url = create_draft_pr(&worktree, title, body)?;\n\n// after\nlet title = title.trim();\nif title.is_empty() {\n    return Err(anyhow!(\"PR title is required\"));\n}\nlet url = create_draft_pr(&worktree, title, body)?;","handlingStrategy":"validation","validationCode":"fn ensure_pr_title(title: &str) -> anyhow::Result<&str> {\n    let t = title.trim();\n    if t.is_empty() {\n        anyhow::bail!(\"PR title is required\");\n    }\n    Ok(t)\n}\n\nlet title = ensure_pr_title(title)?;\nlet url = create_draft_pr(&worktree, title, body)?;","typeGuard":null,"tryCatchPattern":"match create_draft_pr(&worktree, title, body) {\n    Ok(url) => Ok(url),\n    Err(e) if format!(\"{e}\").contains(\"title cannot be empty\") => {\n        // fall back to latest commit subject, then retry\n        let fallback = latest_commit_subject(&worktree)?;\n        create_draft_pr(&worktree, &fallback, body)\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Require the title field in the PR form with client-side validation.","Default the title to the latest commit subject when the user leaves it blank.","Do not strip template tokens down to nothing in upstream sanitization."],"tags":["git","worktree","validation","pull-request","input"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}