{"record":{"id":"944d58913811e9b5","repo":"zeroclaw-labs/zeroclaw","slug":"create-ticket-requires-a-non-empty-summary","errorCode":null,"errorMessage":"create_ticket requires a non-empty summary","messagePattern":"create_ticket requires a non-empty summary","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-tools/src/jira_tool.rs","lineNumber":848,"sourceCode":"                .into(),\n            error: None,\n        })\n    }\n\n    #[allow(clippy::too_many_arguments)]\n    async fn create_ticket(\n        &self,\n        project_key: &str,\n        issue_type: &str,\n        summary: &str,\n        description: Option<&str>,\n        assignee: Option<&str>,\n        labels: Option<&[String]>,\n        parent_key: Option<&str>,\n    ) -> anyhow::Result<ToolResult> {\n        validate_project_key(project_key)?;\n        if summary.trim().is_empty() {\n            anyhow::bail!(\"create_ticket requires a non-empty summary\");\n        }\n        if issue_type.trim().is_empty() {\n            anyhow::bail!(\"create_ticket requires a non-empty issue_type\");\n        }\n        if let Some(parent) = parent_key {\n            validate_issue_key(parent)?;\n        }\n\n        let mut fields = serde_json::Map::new();\n        fields.insert(\"project\".into(), json!({ \"key\": project_key }));\n        fields.insert(\"issuetype\".into(), json!({ \"name\": issue_type }));\n        fields.insert(\"summary\".into(), json!(summary));\n\n        if let Some(desc) = description {\n            let value = if self.is_cloud() {\n                build_adf(desc, &HashMap::new())\n            } else {\n                json!(desc)","sourceCodeStart":830,"sourceCodeEnd":866,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-tools/src/jira_tool.rs#L830-L866","documentation":"Client-side guard in create_ticket: after the project key passes validation, the summary argument is checked with trim() and the call aborts before any HTTP request if it is empty or whitespace-only. Jira itself requires a summary, so the tool rejects the request early. This is purely an input-validation error.","triggerScenarios":"Calling create_ticket with summary=\"\" or summary=\"   \"; a tool-caller/LLM omitting the summary field and the wrapper defaulting it to an empty string; templates that substitute an empty variable (e.g. missing bug title) into the summary.","commonSituations":"Agent-generated ticket payloads where the model left the summary out; form handling that passes uninitialized strings; CI scripts creating tickets from commit messages when the message is blank.","solutions":["Supply a non-empty summary (any non-whitespace text works; Jira truncates display but accepts long summaries).","Trim user input and fall back to a generated default like \"Untitled\" when the source field is blank.","Validate required fields in your own layer before invoking the tool (see defense below)."],"exampleFix":"// before\njira.create_ticket(\"PROJ\", \"Bug\", \"   \", None, None, None, None).await?; // -> error\n\n// after\nlet summary = user_title.trim();\nlet summary = if summary.is_empty() { format!(\"Automated report {}\", chrono_today()) } else { summary };\njira.create_ticket(\"PROJ\", \"Bug\", &summary, None, None, None, None).await?;","handlingStrategy":"validation","validationCode":"let summary = raw_summary.trim();\nassert!(!summary.is_empty(), \"summary required\");\njira.create_ticket(\"PROJ\", \"Task\", summary, None, None, None, None).await?;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate required string fields in your payload layer before calling the tool.","Generate fallback summaries from context (timestamp + source) instead of sending blanks.","Trim input at the edge (CLI/JSON parsing) so whitespace-only never reaches the tool."],"tags":["jira","parameter-validation","create-ticket"],"backgroundTag":"missing-required-field","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}