Common Pitfalls When Writing GPT‑Image 2 Prompts: 10 Mistakes to Avoid
The most common pitfalls when writing GPT‑Image 2 prompts include submitting empty or over‑length strings, mismatched field names, missing language parameters, and ambiguous phrasing that confuses the model.
GPT‑Image 2 sends every user prompt through a multi‑stage pipeline: the React UI in src/main.jsx collects input, shared/apimart.js builds a standardized payload, and api/generate-image.js validates it before forwarding to the Apimart backend. Because validation occurs on both client and server, inconsistencies in prompt construction can trigger 400 errors, waste API credits, or produce unexpected images. Below are the ten most frequent mistakes developers and users make, grounded in the actual source code of the freestylefly/awesome-gpt-image-2 repository.
Empty or Whitespace‑Only Prompts
The submitPersonalGeneration function in src/apimartClient.js performs a truthiness check on the trimmed prompt: if (!prompt) …. However, if the UI fails to trim user input before calling this function, a string containing only spaces bypasses the guard and triggers a 400 error from the Apimart API.
Always apply String(prompt).trim() in the UI layer before any network request. Reject empty results immediately with a clear user message.
Prompts Exceeding the 300‑Character Limit
The constant APIMART_MAX_PROMPT_LENGTH is defined in api/generate-image.js and caps prompts at 300 characters. The production UI does not enforce this limit live, so users discover the restriction only after a failed server round‑trip.
Implement client‑side validation in src/main.jsx with a real‑time character counter. Use the same constant imported from a shared location to prevent drift between client and server limits.
Missing or Mismatched Language Parameters
buildApimartGenerationPayload in shared/apimart.js expects a language option that defaults to 'en'. Some UI components read navigator.language while others hardcode 'en', causing locale mismatches where the generated image does not match the user's interface language.
Centralize locale detection in src/utils/locale.js and pass the resolved value explicitly through every call chain:
import { buildApimartGenerationPayload } from '../shared/apimart';
const payload = buildApimartGenerationPayload(prompt, {
language: navigator.language || 'en'
});
Non‑String Prompt Types
Unit tests in shared/apimart.test.js deliberately pass numbers to verify coercion, but production code can accidentally receive numeric input from uncontrolled form elements. The String() conversion produces technically valid but semantically broken prompts like "123".
Validate that the coerced string contains at least one alphabetic character before submission. This catches both numeric inputs and pure punctuation mistakes.
Double‑Escaped Special Characters
The prompt is serialized with JSON.stringify before transmission. If UI code manually escapes backslashes or quotes first, the result is double‑escaped garbage that corrupts the request body.
Rely exclusively on JSON.stringify for serialization. Never apply manual escaping in frontend code.
Wrong Field Name in Custom Clients
The backend expects p_prompt internally, but the client sends prompt. The remapping happens in api/generate-image.js within the reserveGeneration function. Custom client implementations that skip this file and call the API directly often send p_prompt incorrectly or omit it entirely, causing silent failures.
Import buildApimartGenerationPayload from shared/apimart.js in all clients. It is the single source of truth for field names and structure.
Ignoring API Rate Limits
The UI does not debounce rapid "Generate" clicks, allowing users to spawn overlapping requests. The Apimart service responds with HTTP 429, but the error message is generic and confusing.
Add lodash.debounce to src/main.jsx with a 500‑ms delay and a visible loading state. Display "Please wait, generating…" to prevent accidental double‑submission.
import debounce from 'lodash.debounce';
const handleSubmit = debounce(async (prompt) => {
await submitPersonalGeneration(prompt, apiKey, language);
}, 500, { leading: true, trailing: false });
Missing Access Tokens for Platform Generations
submitPlatformGeneration in shared/apimart.js requires an accessToken retrieved from Supabase. If the user is not authenticated or the token is omitted, the backend treats the request as anonymous and returns an unhelpful error.
Guard the generate button behind an auth check in src/supabaseClient.js. Attach the token automatically when available:
const token = await supabase.auth.getSession();
if (!token) return alert('Please sign in to generate images');
await submitPlatformGeneration(prompt, token, language);
Ambiguous or Contradictory Phrasing
While not a code bug, vague prompts like "a red apple on a blue sky, but the sky is orange" exploit no validation rules yet consistently waste credits on unsatisfactory outputs. The model prioritizes conflicting directives unpredictably.
Encourage concise, single‑focus prompts. Reference the templates in docs/templates.md for structure:
"A serene sunrise over a misty mountain lake, hyper-realistic, 4k resolution"
This includes a clear subject, single focus, and optional style cues without contradiction.
Validation Logic Duplication Across Client and Server
Both src/main.jsx and api/generate-image.js independently check for empty prompts and length violations. Developers who modify only one location introduce subtle bugs where the client accepts input that the server rejects.
Extract all validation into a shared helper used on both ends. The repository already does this for payload building—extend the pattern to validation rules.
Summary
- Trim and validate prompts for emptiness before any network call.
- Enforce the 300‑character limit on the client with live feedback.
- Pass
languageexplicitly from a centralized locale helper. - Coerce and sanity‑check input types to catch numeric garbage.
- Avoid manual escaping—let
JSON.stringifyhandle serialization. - Use
buildApimartGenerationPayloadas the single field‑name authority. - Debounce submissions to prevent rate‑limit errors.
- Require authentication before platform generations.
- Write focused, non‑contradictory prompts guided by template examples.
- Keep validation DRY by sharing logic between client and server.
Frequently Asked Questions
What happens if I send a prompt longer than 300 characters?
The server endpoint in api/generate-image.js rejects the request with an error before contacting the Apimart API. You waste no external credits, but the round‑trip delay degrades user experience. Enforce the same limit client‑side to catch this instantly.
Why does my prompt work in testing but fail in production?
The test suite in shared/apimart.test.js uses mocks that may not replicate the full validation stack. Production calls pass through api/generate-image.js, which applies additional checks. Verify that your test cases include length, emptiness, and type validation.
How do I handle multilingual prompts correctly?
Always pass navigator.language (or your app's active locale) through buildApimartGenerationPayload. Never rely on the default 'en' fallback, as it mismatches the user's expectations and can produce culturally inappropriate imagery.
Can I call the Apimart API directly without using the shared helpers?
Technically yes, but you risk field‑name mismatches (prompt vs p_prompt), incorrect JSON structure, and missing language parameters. The repository provides shared/apimart.js precisely to eliminate these inconsistencies—use it.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →