Server-side-only validation for empty or oversized inputs forces every request through a full network round-trip before a basic error surfaces, wasting LLM API spend on requests that will be rejected and burning user patience on latency that could be zero. A user pasting a 200KB document into a chat box discovers the limit after the spinner, not before. Client-side input validation short-circuits these failures at the keyboard, cutting wasted provider tokens and improving perceived performance for the user-experience taxon this pattern tracks.
Low because the failure mode is latency and wasted tokens, not data loss or security compromise.
Add a character-count check and disabled submit button to the chat input component at src/components/chat-input.tsx. Track input length in local state, compute isOverLimit against a fixed ceiling, and block the form onSubmit when the input is empty or exceeds it. Show a live counter past a warning threshold so users self-correct before sending.
const MAX_CHARS = 20000;
const isOverLimit = input.length > MAX_CHARS;
<button type="submit" disabled={!input.trim() || isOverLimit}>Send</button>
ID: ai-token-optimization.streaming-performance.client-side-input-validation
Severity: low
What to look for: In the chat input component or form, look for client-side validation of the input length before the form submits. This could be: a character or word count check, a disabled submit button when input is empty or exceeds a threshold, a visual token counter displayed to the user, or a client-side import of a tokenizer library. Also check for server-side-only validation where the request must round-trip before basic input errors are caught. Count all instances found and enumerate each.
Pass criteria: The UI prevents or warns on submission when user input is empty or clearly exceeds a reasonable limit (e.g., character count > 20,000). Ideally, a token counter is shown so users can manage their input length proactively. At least 1 implementation must be confirmed.
Fail criteria: Validation is server-side only — the frontend submits any input length without client-side checks, requiring a round-trip before basic errors (empty input, excessively long input) are caught.
Skip (N/A) when: The application has no user input form — it operates entirely on server-side or programmatically generated prompts.
Signal: No <input>, <textarea>, or useChat hook usage in any frontend component.
Detail on fail: "No client-side input validation — empty or oversized inputs require server round-trip to catch"
Remediation: Server-side validation for basic input errors (empty, too long) adds unnecessary latency and wastes server resources. Client-side checks catch these immediately.
// src/components/chat-input.tsx
const MAX_CHARS = 20000;
const WARN_CHARS = 15000;
export function ChatInput({ onSubmit }: { onSubmit: (input: string) => void }) {
const [input, setInput] = useState("");
const isOverLimit = input.length > MAX_CHARS;
const isNearLimit = input.length > WARN_CHARS;
return (
<form onSubmit={e => { e.preventDefault(); if (!isOverLimit && input.trim()) onSubmit(input); }}>
<textarea
value={input}
onChange={e => setInput(e.target.value)}
maxLength={MAX_CHARS + 100} // soft enforcement
/>
{isNearLimit && (
<p style={{ color: isOverLimit ? "red" : "orange" }}>
{input.length.toLocaleString()} / {MAX_CHARS.toLocaleString()} characters
{isOverLimit && " — input too long"}
</p>
)}
<button type="submit" disabled={input.trim().length === 0 || isOverLimit}>
Send
</button>
</form>
);
}
Verify by attempting to submit an empty message (button should be disabled) and pasting a very long text (counter should appear and submission should be blocked).