JSON Response Issue with Roboflow Inference API in Deployed Web App

I’m facing an issue with my web app when using the Roboflow Inference API after deployment. Locally, the endpoint returns the expected JSON response, but once deployed, it occasionally returns an HTML response (e.g., <!DOCTYPE html>), which causes a SyntaxError: Unexpected token '<'. This happens despite the endpoint responding with a 200 OK status.

  • Project Type:Parking Management System with license plate detection (ALPR).
  • Operating System & Browser: Chrome
  • Project Universe Link or Workspace/Project ID:
  • API Endpoint Used: Roboflow Inference API
  • Problem Details:
  • The web app fetches frames from a video feed and sends them to the /detect endpoint in my Flask server.
  • The Flask server calls the Roboflow model inference API and should return the detected license plate text and vehicle type as JSON.
  • The server logs show a 200 OK response, but the client sometimes receives unexpected HTML instead of JSON.**

Additional Note: This is deploy on Render.

This is the related codes below.

Load the model

print(“Loading model…”)
model = inference.get_model(“plate-number-recognition-prqx4/2”)
print(“Model successfully loaded.”)

import easyocr
from PIL import Image
import numpy as np
from flask import request, jsonify

Initialize the easyocr reader

reader = easyocr.Reader([‘en’])

@parking.route(‘/detect’, methods=[‘POST’])
def detect():
if ‘image’ not in request.files:
print(“No image uploaded”)
return jsonify({‘error’: ‘No image uploaded’}), 400

try:
    # Get the image from the request
    file = request.files['image']
    img = Image.open(file.stream)
    img_np = np.array(img)  # Convert PIL Image to numpy array for processing

    # Run inference
    print("Running inference...")
    result = model.infer(image=img_np)
    print("Inference result:", result)

    if len(result) > 0:
        response = result[0]
        detected_text = ""
        vehicle_type_detected = None

        for prediction in response.predictions:
            x1 = prediction.x - (prediction.width / 2)
            x2 = prediction.x + (prediction.width / 2)
            y1 = prediction.y - (prediction.height / 2)
            y2 = prediction.y + (prediction.height / 2)

            # Crop the license plate from the image
            license_plate = img_np[int(y1):int(y2), int(x1):int(x2)]
            license_plate_image = Image.fromarray(license_plate)

            # Use easyocr to extract text from the cropped license plate
            extracted_text = reader.readtext(np.array(license_plate_image), detail=0, paragraph=True)

            if extracted_text:
                # Clean and validate the extracted text
                cleaned_text = extracted_text[0].strip().replace(" ", "").upper()
                validated_text, vehicle_type = validate_vehicle_plate(cleaned_text, vehicle_type='both')

                if validated_text != "Invalid plate format":
                    detected_text += validated_text + " "
                    vehicle_type_detected = vehicle_type  # Set the detected vehicle type

        print("Detected text:", detected_text.strip())
        print("Vehicle type detected:", vehicle_type_detected)

        return jsonify({
            'text': detected_text.strip(),
            'vehicle_type': vehicle_type_detected
        })
    else:
        print("No plates detected")
        return jsonify({'text': 'No plates detected', 'vehicle_type': 'Unknown'}), 200
except Exception as e:
    print("Error during inference or processing:", e)
    return jsonify({'error': 'Inference error'}), 500

javascript

function processVideo() {
const canvas = document.createElement(‘canvas’);
const context = canvas.getContext(‘2d’);

            setInterval(() => {
                canvas.width = video.videoWidth;
                canvas.height = video.videoHeight;
        
                context.drawImage(video, 0, 0, canvas.width, canvas.height);
        
                canvas.toBlob((blob) => {
                    const formData = new FormData();
                    formData.append('image', blob, 'frame.jpg');
        
                    fetch('/parking/detect', {
                        method: 'POST',
                        body: formData
                    })
                    .then(response => {
                        // Log the content type to verify JSON
                        console.log('Response content type:', response.headers.get('Content-Type'));
                        
                        return response.json(); // Attempt to parse as JSON
                    })
                    .then(data => {
                        console.log('Received data:', data); // Log the response
        
                        if (data.text) {
                            detectedText.value = data.text;  // Display detected plate number
                        }
                        if (data.vehicle_type) {
                            detectedVehicleType.value = data.vehicle_type;  // Display vehicle type
                        }
                    })
                    .catch(error => console.error("Error processing the frame or invalid JSON response: ", error));
                }, 'image/jpeg');
            }, 2000);  // Process every 2 seconds
        }

Hi @Erica_Inosanto,

Thank you for taking time to report this issue!

When you encounter unexpected response, can you record and share whole body? I suspect the issue you encounter might be due to error thrown by inference web server and remainder of the message might hold more details on the nature of that error.

Many thanks in advance,
Grzegorz

1 Like

Hello. I do not understand the whole body, but is this it? Also thank you so much for helping, appreciate it!

Hello. Kindly help me pls.

Hi @Erica_Inosanto ,

Thanks for sharing console log!

In your browser debug tools there should be a Network tab, can you find the offending request in the list of requests and share content of request and response?

Thanks!
Grzegorz

Hello. Is this what you are pertaining to?



Hi @Erica_Inosanto ,

Based on screenshots and also your original message I understand you host your script on Cloudflare or you have Cloudflare setup as proxy.

502 error you shared does not provide much information, but I see you also received 500 error - can you share Response screenshot for requests that resulted in 500 error?

Regarding deployment - do you have access to server logs? Server logs would provide exact reason why you receive error 500. Please share python logs from your server if you have access to them.