How to Troubleshoot Common Prompt Generation Failures in awesome-gpt-image-2

Troubleshoot common prompt generation failures by tracing the request flow through authentication validation, prompt length checks, Supabase credit reservations, and APIMart upstream submissions while monitoring for specific error codes like INVALID_PROMPT, CREDITS_REQUIRED, and UPSTREAM_BUSY returned by the API endpoints.

The awesome-gpt-image-2 service generates images by forwarding user prompts to the APIMart provider and tracking requests through a reservation system stored in Supabase. When you troubleshoot common prompt generation failures, you must examine the four-layer pipeline: client validation in api/generate-image.js, credit reservation via RPC functions, upstream submission to APIMart, and status polling through api/generation/status.js.

Understanding the Generation Pipeline Architecture

The service processes image generation through distinct phases coordinated across several modules. In api/generate-image.js, the handler first verifies server configuration through isServerConfigured(), which checks both getApimartConfig() and isSupabaseServerConfigured() from api/_lib/supabase.js. The request then passes through getAuthContext to validate the JWT and retrieve the user profile before proceeding to prompt validation and the reservation layer.

Common Failure Points and Resolution Strategies

Authentication and Configuration Errors

Before processing any generation request, the endpoint verifies that both APIMart and Supabase environments are properly configured. If isServerConfigured() returns false, the service cannot proceed. Authentication failures occur when getAuthContext detects an invalid or missing JWT, returning a 401 status immediately.

To resolve these issues:

  • Verify that environment variables for APIMart API keys and Supabase credentials are populated in the server configuration
  • Check that the request includes a valid Authorization: Bearer <token> header or valid Supabase session cookie
  • Ensure the request method is either GET (for status checks) or POST (for new generations); other methods return 405 Method Not Allowed

Prompt Validation Failures

The system strictly enforces prompt constraints in api/generate-image.js. The validation logic converts the input to a string, trims whitespace, and verifies that prompt is non-empty, does not exceed APIMART_MAX_PROMPT_LENGTH (defined in shared/apimart.js), and that caseId is a finite number.

const prompt = String(body.prompt || '').trim();
const caseId = Number(body.caseId);
if (!prompt ||
    prompt.length > APIMART_MAX_PROMPT_LENGTH ||
    !Number.isFinite(caseId)) {
  return json(res, 400, { ok:false, error:'INVALID_PROMPT' });
}

An INVALID_PROMPT error (HTTP 400) indicates either an empty prompt, text exceeding the provider's length limit, or a missing/invalid caseId. Verify that your JSON payload includes both fields correctly formatted.

Credit Reservation and Database Errors

After validation, the service attempts to reserve credits through the reserve_generation_usage Supabase RPC function. This creates a temporary record in the generation_reservations table with status pending via the reserveGeneration helper.

The reservation layer returns specific error codes:

  • CREDITS_REQUIRED (HTTP 402): The user has insufficient free or paid credits. Check the user's credit balance in the Supabase dashboard.
  • GENERATION_FAILED (HTTP 500): A database or internal RPC error occurred. Inspect Supabase logs for connection issues or schema mismatches.

If reservation succeeds but upstream submission fails, the system automatically calls releaseReservation() to roll back the credit hold and prevent phantom charges.

Upstream Provider Failures

The submitApimartGeneration function in api/_lib/apimart.js forwards the prompt to APIMart. Common upstream errors map to specific HTTP status codes through the publicErrorCode helper in api/generate-image.js:

APIMart Error Public Error Code HTTP Status Resolution
APIMART_RATE_LIMITED UPSTREAM_BUSY 503 Implement exponential backoff and retry using the Retry-After header
APIMART_API_KEY_INVALID SERVER_NOT_CONFIGURED 500 Verify APIMART_API_KEY environment variable is valid
APIMART_BALANCE_REQUIRED SERVER_NOT_CONFIGURED 500 Add funds to the APIMart account balance
APIMART_REQUEST_REJECTED APIMART_REQUEST_REJECTED 502 The provider rejected the prompt content; modify the prompt text
Other errors GENERATION_FAILED 502 Contact APIMart support or check provider status page

Monitoring Generation Status and Final Delivery

After receiving a 202 Accepted response with a taskId, clients must poll /api/generation/status to retrieve the final result. The api/generation/status.js endpoint performs two operations: it queries the local Supabase reservation via findPlatformGeneration from api/_lib/generation.js, and if the status is still pending, it fetches the current state from APIMart using getApimartTask.

In status.js, the statusForError helper maps specific APIMart codes to HTTP responses:

  • 404 Not Found: The taskId does not exist in the database
  • 429 Too Many Requests: The APIMart provider is rate-limiting status queries (mapped from APIMART_RATE_LIMITED)
  • 400 Bad Request: Invalid taskId format (APIMART_INVALID_TASK)
  • 502 Bad Gateway: Upstream communication failure

When APIMart reports completion, settlePlatformGeneration updates the reservation record with the final image URL, cost, and expiration timestamp extracted by providerFieldsForTask.

Step-by-Step Troubleshooting Checklist

Follow this systematic approach to isolate generation failures:

  1. Validate Request Format: Ensure Content-Type: application/json and the body contains prompt (string) and caseId (number).

  2. Verify Authentication: Confirm the request returns 200 OK on GET /api/generate-image (auth status check). If 401, refresh the JWT.

  3. Check Prompt Constraints: Verify prompt length ≤ APIMART_MAX_PROMPT_LENGTH and that caseId is a valid number to avoid INVALID_PROMPT errors.

  4. Inspect Credit Balance: Query the Supabase generation_reservations table. If error_code equals CREDITS_REQUIRED, the user needs to purchase credits.

  5. Review Upstream Configuration: SERVER_NOT_CONFIGURED (500) indicates missing APIMart credentials or insufficient provider account balance.

  6. Handle Rate Limiting: On UPSTREAM_BUSY (503), respect the Retry-After header before retrying the request.

  7. Poll Correctly: After 202 response, use the returned taskId to query /api/generation/status?taskId=... until status reaches completed or failed.

  8. Analyze Server Logs: Check for warnings containing "Failed to query APIMart generation task" in api/generation/status.js to identify upstream connectivity issues.

Example: Implementing a Resilient Generation Client

This implementation handles the full lifecycle including error detection and status polling:

async function generateImage(prompt, caseId, language = 'en') {
  // Submit generation request
  const submit = await fetch('/api/generate-image', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ prompt, caseId, language })
  });
  const start = await submit.json();

  if (!start.ok) {
    // Handle specific error codes
    if (start.error === 'CREDITS_REQUIRED') {
      throw new Error('Insufficient credits. Please purchase more.');
    }
    if (start.error === 'INVALID_PROMPT') {
      throw new Error('Prompt too long or caseId invalid.');
    }
    throw new Error(start.error);
  }

  const taskId = start.taskId;

  // Poll until completion
  while (true) {
    const resp = await fetch(`/api/generation/status?taskId=${taskId}`);
    const status = await resp.json();

    if (!status.ok) {
      if (status.error === 'UPSTREAM_BUSY') {
        await new Promise(r => setTimeout(r, 5000)); // Wait 5s before retry
        continue;
      }
      throw new Error(status.error);
    }
    
    if (status.status === 'completed') return status.image;
    if (status.status === 'failed') throw new Error(status.errorMessage);
    
    await new Promise(r => setTimeout(r, 2000)); // Standard polling interval
  }
}

Summary

  • Authentication failures return 401 and require valid JWT tokens or session cookies configured in api/_lib/supabase.js.
  • Validation errors produce INVALID_PROMPT (400) when prompts exceed APIMART_MAX_PROMPT_LENGTH or caseId is malformed.
  • Credit issues trigger CREDITS_REQUIRED (402) during the reserve_generation_usage RPC call in Supabase.
  • Upstream problems manifest as UPSTREAM_BUSY (503) for rate limits or SERVER_NOT_CONFIGURED (500) for invalid APIMart credentials.
  • Status polling via /api/generation/status tracks final delivery, with 404 indicating unknown tasks and 429 signaling excessive polling frequency.

Frequently Asked Questions

Why does my request return "INVALID_PROMPT" even when I provide text?

The INVALID_PROMPT error occurs in api/generate-image.js when the prompt string is empty after trimming, exceeds the APIMART_MAX_PROMPT_LENGTH constant defined in shared/apimart.js, or when the caseId parameter is missing or not a finite number. Ensure your JSON payload includes both prompt as a non-empty string and caseId as a valid numeric value.

How do I handle the "UPSTREAM_BUSY" error when generating images?

The UPSTREAM_BUSY status code (503) indicates that APIMart is currently rate-limiting requests. The api/generate-image.js endpoint maps APIMART_RATE_LIMITED to this error code. Implement exponential backoff in your client, respecting the Retry-After response header if present, or wait 5-10 seconds before retrying the generation request.

What should I check when receiving a "SERVER_NOT_CONFIGURED" error?

This 500 error indicates that the server cannot communicate with APIMart, either because the APIMART_API_KEY environment variable is invalid or the APIMart account has insufficient balance. Verify your environment configuration in getApimartConfig() and ensure the provider account has available credits or a positive balance.

How do I verify if a generation completed successfully after receiving a 202 response?

After receiving a 202 Accepted response with a taskId, poll the /api/generation/status endpoint using the findPlatformGeneration utility. The endpoint returns completed with an image URL when finished, failed with an error message if the generation error occurred, or pending if the task is still processing. A 404 response indicates the taskId was not found in the Supabase generation_reservations table.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →