{"record":{"id":"fa7eebd6105a83c5","repo":"bytedance/deer-flow","slug":"input-text-is-required","errorCode":null,"errorMessage":"Input text is required","messagePattern":"Input text is required","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"backend/app/gateway/routers/input_polish.py","lineNumber":80,"sourceCode":"    description=\"Rewrite a draft message before it is sent. This does not create a thread run or persist any message.\",\n)\n@require_permission(\"runs\", \"create\")\nasync def polish_input(\n    body: InputPolishRequest,\n    request: Request,\n    config: AppConfig = Depends(get_config),\n) -> InputPolishResponse:\n    del request  # Required by the auth decorator.\n\n    if not config.input_polish.enabled:\n        raise HTTPException(status_code=404, detail=\"Input polishing is disabled\")\n\n    # Validate the same normalized view of the input that we send to the model,\n    # so the user-facing length boundary and the model input cannot disagree\n    # (e.g. a padded draft passing the check but arriving with stray whitespace).\n    text = body.text.strip()\n    if not text:\n        raise HTTPException(status_code=400, detail=\"Input text is required\")\n\n    max_chars = config.input_polish.max_chars\n    if len(text) > max_chars:\n        raise HTTPException(status_code=400, detail=f\"Input text exceeds {max_chars} characters\")\n\n    model_name = config.input_polish.model_name\n    try:\n        raw = await run_oneshot_llm(\n            system_instruction=_build_system_instruction(),\n            user_content=_build_user_content(text, body.locale),\n            run_name=\"input_polish\",\n            app_config=config,\n            model_name=model_name,\n            thread_id=body.thread_id,\n        )\n        rewritten = _clean_rewritten_text(raw)\n    except Exception as exc:\n        logger.exception(\"Failed to polish input: thread_id=%s err=%s\", body.thread_id, exc)","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/app/gateway/routers/input_polish.py#L62-L98","documentation":"Raised by POST /input-polish with status 400 when the request text, after stripping surrounding whitespace, is empty. The endpoint validates the normalized view of the input it would send to the model, so whitespace-only drafts ('   ', '\\n\\t') are rejected identically to empty strings — preventing padded drafts from passing the check but wasting a model call.","triggerScenarios":"Sending {\"text\": \"\"}, {\"text\": \"   \"}, or {\"text\": \"\\n\"}; a polish button enabled on an empty composer; autosubmit logic firing before the user types.","commonSituations":"UI not disabling the polish action on empty input; whitespace left after the user deletes their message; paste of whitespace-only content.","solutions":["Client-side check: trim the draft and skip the request when empty.","Disable/gray out the polish control until the composer has non-whitespace text.","Strip pasted content and validate before enqueueing the polish call."],"exampleFix":"// before\nif (draft.length > 0) await polish({ text: draft }); // '   ' passes -> 400\n\n// after\nconst text = draft.trim();\nif (text) await polish({ text });","handlingStrategy":"validation","validationCode":"const text = draft.trim();\nif (!text) return; // never call polish with empty/whitespace input","typeGuard":"const hasPolishableText = (s: string) => s.trim().length > 0;","tryCatchPattern":null,"preventionTips":["Trim and check emptiness client-side before the request","Disable the polish action on an empty composer","Handle paste events by validating the resulting text"],"tags":["http-400","validation","input-polish","empty-input"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}