Description
The AI endpoints parse Gemini responses using JSON.parse() but do not validate the structure of the returned JSON before sending it to the frontend.
Currently, the backend only verifies that the response is valid JSON, not that it matches the expected schema.
For example, in aiController.js:
const data = JSON.parse(cleanedText);
res.status(200).json({ model: usedModel, ...data });
If Gemini returns:
{
"question": "Explain closures"
}
instead of the expected:
{
"question": "Explain closures",
"answer": "A closure is..."
}
the API still returns a successful response.
Impact
Frontend may receive incomplete AI responses
Missing fields can cause rendering issues
API contract between backend and frontend is not guaranteed
Unexpected Gemini responses can silently pass through
Steps to Reproduce
Call an AI endpoint such as:
POST /api/ai/generate-questions
POST /api/ai/generate-explanation
Modify the prompt temporarily or simulate an incomplete Gemini response.
Observe that the backend accepts the JSON response as long as it is syntactically valid.
Expected Behavior
The backend should validate the parsed Gemini response before returning it.
Example:
For generated questions:
[
{
"question": "string",
"answer": "string"
}
]
For explanations:
{
"title": "string",
"explanation": "string"
}
Suggested Fix
Add response schema validation after parsing Gemini output.
Example using Joi:
const schema = Joi.array().items(
Joi.object({
question: Joi.string().required(),
answer: Joi.string().required()
})
);
const { error } = schema.validate(data);
if (error) {
return res.status(500).json({
message: "Invalid AI response format"
});
}
This will ensure only correctly structured AI responses reach the frontend.
Description
The AI endpoints parse Gemini responses using JSON.parse() but do not validate the structure of the returned JSON before sending it to the frontend.
Currently, the backend only verifies that the response is valid JSON, not that it matches the expected schema.
For example, in aiController.js:
const data = JSON.parse(cleanedText);
res.status(200).json({ model: usedModel, ...data });
If Gemini returns:
{
"question": "Explain closures"
}
instead of the expected:
{
"question": "Explain closures",
"answer": "A closure is..."
}
the API still returns a successful response.
Impact
Frontend may receive incomplete AI responses
Missing fields can cause rendering issues
API contract between backend and frontend is not guaranteed
Unexpected Gemini responses can silently pass through
Steps to Reproduce
Call an AI endpoint such as:
POST /api/ai/generate-questions
POST /api/ai/generate-explanation
Modify the prompt temporarily or simulate an incomplete Gemini response.
Observe that the backend accepts the JSON response as long as it is syntactically valid.
Expected Behavior
The backend should validate the parsed Gemini response before returning it.
Example:
For generated questions:
[
{
"question": "string",
"answer": "string"
}
]
For explanations:
{
"title": "string",
"explanation": "string"
}
Suggested Fix
Add response schema validation after parsing Gemini output.
Example using Joi:
const schema = Joi.array().items(
Joi.object({
question: Joi.string().required(),
answer: Joi.string().required()
})
);
const { error } = schema.validate(data);
if (error) {
return res.status(500).json({
message: "Invalid AI response format"
});
}
This will ensure only correctly structured AI responses reach the frontend.