bytedance/deer-flow · warning · HTTPException
Input text exceeds {max_chars} characters
Error message
Input text exceeds {max_chars} characters What it means
Raised by POST /input-polish with status 400 when the trimmed text length exceeds config.input_polish.max_chars. The limit is enforced server-side on the same normalized string sent to the model, keeping the user-facing boundary and the LLM input consistent. The response detail includes the configured max so clients can display it.
Source
Thrown at backend/app/gateway/routers/input_polish.py:84
body: InputPolishRequest,
request: Request,
config: AppConfig = Depends(get_config),
) -> InputPolishResponse:
del request # Required by the auth decorator.
if not config.input_polish.enabled:
raise HTTPException(status_code=404, detail="Input polishing is disabled")
# Validate the same normalized view of the input that we send to the model,
# so the user-facing length boundary and the model input cannot disagree
# (e.g. a padded draft passing the check but arriving with stray whitespace).
text = body.text.strip()
if not text:
raise HTTPException(status_code=400, detail="Input text is required")
max_chars = config.input_polish.max_chars
if len(text) > max_chars:
raise HTTPException(status_code=400, detail=f"Input text exceeds {max_chars} characters")
model_name = config.input_polish.model_name
try:
raw = await run_oneshot_llm(
system_instruction=_build_system_instruction(),
user_content=_build_user_content(text, body.locale),
run_name="input_polish",
app_config=config,
model_name=model_name,
thread_id=body.thread_id,
)
rewritten = _clean_rewritten_text(raw)
except Exception as exc:
logger.exception("Failed to polish input: thread_id=%s err=%s", body.thread_id, exc)
raise HTTPException(status_code=503, detail="Failed to polish input") from exc
if not rewritten:
raise HTTPException(status_code=503, detail="Failed to polish input")View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Enforce the same limit client-side (maxLength on the textarea / pre-check trim().length) and show a character counter.
- Split very long drafts or summarize before polishing instead of sending as-is.
- If longer input is genuinely needed, raise input_polish.max_chars in config.yaml.
Example fix
// before
await polish({ text: draft }); // 12k chars -> 400
// after
const MAX = await getInputPolishLimits(); // exposes max_chars
if (draft.trim().length > MAX) {
showWarning(`Draft exceeds ${MAX} characters — trim before polishing`);
} else {
await polish({ text: draft.trim() });
} Defensive patterns
Strategy: validation
Validate before calling
const text = draft.trim();
if (text.length > MAX_CHARS) { warn(`Limit ${MAX_CHARS} chars (you have ${text.length})`); return; }
await polish({ text }); Type guard
const withinPolishLimit = (s: string, max: number) => s.trim().length <= max;
Prevention
- Mirror server max_chars in the client (fetch it, don't hardcode)
- Show a live character counter on long drafts
- Split or summarize oversized pastes before polishing
When it happens
Trigger: Polishing a very long draft (e.g. pasted document) beyond the configured cap; client maxlength differing from server max_chars; lowering max_chars in config while the UI still allows longer input.
Common situations: Users pasting whole files into the composer; environments where operators tune max_chars down for cost; frontend using a stale default limit after a config change.
Related errors
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/2433e7b44be841b8.
Report an issue: GitHub.