Trim over-cap prompts to fit, and say so — instead of dead-ending#369
Merged
Conversation
Contributor
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
nanoodle | df8f832 | Commit Preview URL Branch Preview URL |
Jul 27 2026, 04:41 AM |
…ending
Reported: an LLM node writing the prompt for a qwen-image-3 Image node produced
831 characters and the run died with
400 {"error":"Your prompt is too long for Qwen Image 3. Please shorten it to
800 characters or less (current: 831 characters).","code":"prompt_too_long"}
The prompt was WIRED, so "please shorten it" pointed at a field with no keyboard
behind it — and the LLM call that wrote it had already been paid for.
Not an edge case. Live probe of 183 image models (2026-07-26): 45 enforce a
character cap at the route — 512 (step-image-edit-2), 800 (qwen-image-3, a
Featured model), 1200 (z-image-turbo family), 3000 (40 more). Video caps too
(minimax-hailuo-02 = 2000, lightricks-ltx-2-fast = 3000, in a third message
shape). The edit path caps identically. The catalogs advertise none of it, so
there was no way to know before sending.
What ships: trim to fit at a sentence boundary, and state it three times —
before the run (the node shows the cap and that a longer wired prompt gets
trimmed), at the run (a toast naming the model and the original length), and
after it (a note that stays on the node saying what it cut). Nothing about the
trim is silent, which is the whole basis for doing it.
What deliberately does NOT ship: any rewriting of the graph's own prompts. An
LLM node's system prompt reaches the model exactly as written. Shortening a
prompt to dodge a cap is the user's call to make in their own words, not
something to inject on their behalf — pinned by the guard, both engines.
An unknown model's cap is learned from the live 400 and remembered, so the same
model states its limit up front next run instead of discovering it again.
The cost is measured, not assumed: across 5 chat models on the reported graph,
every one overshot the 800-char cap (1205-2785 chars) and the trim kept 29-62%
of what was written — on a tight model, trimming is the normal path. Four of
five cuts landed on a sentence end; one fell back to a word boundary. The
trimmed 794-char prompt (from 2785) generated on qwen-image-3, the model that
400s at 831.
Also closes the same hole on audio: TTS max_chars IS catalog metadata, but the
editor applied it as a textarea maxlength, which a wired input walks straight
past. It now resolves through the same path.
Both engines — the editor and exported apps, which hit this harder because their
users can't edit the prompt at all. scripts/check-prompt-caps.mjs pins all of it
offline (in pre-commit); scripts/probe-prompt-caps.mjs regenerates the table;
docs/NANOGPT-prompt-length-metadata.md is the upstream ask that would let the
model picker show the cap before anyone loses two thirds of a prompt.
Update: Prompt too long? Image and video models cap how long a prompt can be — Qwen Image 3 stops at 800 characters — and a wired prompt used to fail the run outright. Nanoodle now shows the limit on the node, trims a longer prompt at a sentence boundary, and tells you exactly what it cut.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
mikkel
force-pushed
the
prompt-length-caps
branch
from
July 27, 2026 04:14
6c24503 to
d19f41a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The report
An LLM node writing the prompt for a
qwen-image-3Image node produced 831 characters and the run died:The prompt was wired. "Please shorten it" pointed at a field with no keyboard behind it.
How common (live probe, 183 of 214 image models, 2026-07-26)
45 models enforce a character cap at NanoGPT's route:
step-image-edit-2qwen-image-3— the reported one, and a Featured modelz-image-turbofamilyflux-schnell,qwen-image,hidream,riverflow-2-*, most Runware/CivitAI ids)nano-banana,flux-kontext,seedream-v4.5, …)Video caps too (
minimax-hailuo-02= 2000,lightricks-ltx-2-fast= 3000, in a third error shape with nocodefield). The edit path caps identically. The catalogs advertise none of it —supported_parametershas resolutions, image constraints and LoRA slots, and nothing about text. Raw results:proof/prompt-caps/.What ships
Trim to fit at a sentence boundary — and state it three times. The disclosure is the whole basis for doing it, so it's pinned as hard as the trim is:
prompt limit 800 characters — a longer wired prompt is trimmed to fit, so the limit is visible while there's still time to pick a different model. Typed prompts get a live690 / 800counter, red once over.prompt trimmed to 800 characters for Qwen Image 3 (was 2785).✂ trimmed 2785 → 794 characters to fit.The cut never lands mid-word and never below 70% of the cap; it prefers a sentence end and falls back to a word boundary.
What deliberately does not ship: any rewriting of the graph's own prompts. An LLM node's system prompt reaches the model exactly as written — no injected "keep it under N characters" directive, wired or not. Shortening a prompt to dodge a cap is the user's call to make in their own words. The guard asserts this on both engines (
no upstream prompt-budget injection,the cap code never writes a system field at all).Learning. An unknown model's cap is parsed out of the live 400 and remembered, so the same model states its limit up front next run. Three error shapes are handled; the
current: Nfigure is deliberately not readable as a cap (learning it would grow the limit with every failure).Also closes the same hole on audio: TTS
max_charsis catalog metadata, but it was only a textareamaxlength— a wired input walked straight past it.What the trim actually costs — measured
proof/prompt-caps/verify-trim.mjs, five chat models on the reported graph, with the shippedfitPromptText:celeris-1openai/gpt-5-nanodeepseek-chatclaude-haiku-4-5-20251001meta-llama/llama-4-scoutPlainly: an LLM writing an image prompt overshoots an 800-char cap every time (5/5, by 1.5–3.5×), so on a tight model the trim is the normal path and a third to two thirds of the generated text is dropped. That's the trade — a run that finishes and tells you what it cut, instead of one that fails. Four of five cuts landed on a sentence end;
celeris-1had no boundary above the 70% floor and fell back to a word, which is the fallback working.End to end: the trimmed 794-character prompt (from 2785) generated on
qwen-image-3— the model that 400s at 831. Chrome verified in a real browser via CDP, no key, no spend.Both engines
The editor and exported apps, which hit this harder because their users can't edit the prompt at all.
scripts/check-prompt-caps.mjspins it offline (wired into pre-commit as guard 40); all 40 existing guards pass.Tooling & upstream
scripts/probe-prompt-caps.mjsregenerates the table. Hand-run and spend-capable: route validation runsimages → route resolution → prompt length → model size, so an over-long prompt plus an unsupported size is rejected free when the model caps — models that ignoresize(~40%) generate and charge.--dry-run,--budget,--models,--max-pricebound it; the 2026-07-26 sweep cost $1.60.docs/NANOGPT-prompt-length-metadata.md— the upstream ask.supported_parameters.max_prompt_charson image/video (the audio catalog already does exactly this) would let the model picker show the cap, so someone picks a different model instead of losing two thirds of their prompt.Companion PR for headless/agent runs: nanoodlecom/nanoodle-js#26.
🤖 Generated with Claude Code