{"record":{"id":"b003287f0a7bfa2e","repo":"gitbutlerapp/gitbutler","slug":"field-is-required-b00328","errorCode":null,"errorMessage":"{field} is required","messagePattern":"(.+?) is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-napi/src/ai.rs","lineNumber":60,"sourceCode":"                }\n            },\n        )?;\n        response\n            .filter(|response| !response.trim().is_empty())\n            .context(\"AI provider returned an empty response\")\n    })\n    .await\n    .context(\"AI response task failed\")\n    .and_then(|result| result)\n    .map_err(to_napi_err)?;\n\n    Ok(response)\n}\n\nfn required_message<'a>(value: &'a str, field: &str) -> Result<&'a str> {\n    let value = value.trim();\n    if value.is_empty() {\n        bail!(\"{field} is required\")\n    }\n    Ok(value)\n}\n","sourceCodeStart":42,"sourceCodeEnd":64,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-napi/src/ai.rs#L42-L64","documentation":"required_message validates an AI request string parameter in the N-API binding: if the value is empty or whitespace-only after trimming, it bails with '{field} is required'. Used by stream_ai_response to reject empty prompts/messages before hitting the LLM API.","triggerScenarios":"Calling stream_ai_response (directly or from JS/TS via N-API) with an empty or whitespace-only message/prompt string.","commonSituations":"UI sending an empty input box value, a variable that was never populated, or trim-related regressions stripping the whole message.","solutions":["Provide a non-empty message string","Trim and check length before calling the API","Disable the submit action in the UI while the input is empty"],"exampleFix":"// before\nawait streamAiResponse(\"\")\n// after\nconst msg = input.trim();\nif (!msg) return;\nawait streamAiResponse(msg)","handlingStrategy":"validation","validationCode":"// TS\nif (!message || !message.trim()) {\n  throw new Error('message is required');\n}","typeGuard":"const isNonEmptyMessage = (v: unknown): v is string =>\n  typeof v === 'string' && v.trim().length > 0;","tryCatchPattern":"// TS\ntry {\n  await streamAiResponse(message);\n} catch (e) {\n  if (String(e).includes('is required')) showToast('Enter a message first');\n  else throw e;\n}","preventionTips":["Disable send buttons while input is empty","Trim user input before passing to the API","Guard variables that may be undefined/empty upstream"],"tags":["validation","empty-value","ai","napi"],"backgroundTag":"empty-required-field","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}