AOSSIE-Org / AOSSIE-Org/Ell-ena

BUG: Unsafe JSON parsing in generateChatResponse() may cause runtime crashes on malformed Gemini responses

Open
#170 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Dart
Stars
54
Forks
110
PR merge metrics
No merged PRs in 30d

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### What happened?

📌 Issue Overview

The current implementation of generateChatResponse() assumes that the Gemini API response always follows a fixed structure, specifically:

A non-empty candidates list
A nested content object
A parts list
Either a text field or a functionCall object

For example, the code previously accessed nested fields like this:
```dart
final candidates = responseData['candidates'] as List;
final content = candidates[0]['content'];
final parts = content['parts'];
```

This approach performs unsafe casting and deep indexing. Since the response originates from an external API, its structure cannot be guaranteed. In cases such as rate limits, server errors, or unexpected payload formats, fields like candidates may be missing, empty, or structured differently.

If that happens, accessing values using:

```dart
candidates[0]['content']['parts'][0]['text']
```

may lead to runtime exceptions such as TypeError, NoSuchMethodError, or RangeError.

This creates a stability risk in the AI response pipeline.

🎯 Expected Behavior

The application should validate the structure of the API response before accessing nested fields and return a controlled error response if the structure is invalid.

🚨 Actual Behavior

The current implementation assumes a valid structure and directly casts and indexes nested fields, which may result in runtime crashes if the API response does not match the expected schema.

💡 Suggested Improvements

Refactor the response parsing block in generateChatResponse() to defensively validate the response before accessing nested data.

For example:
```dart
final candidates = responseData['candidates'];

if (candidates is! List || candidates.isEmpty) {
return {
'type': 'error',
'content': 'Invalid or empty response from API',
};
}
```

Additionally:

Validate content exists and is a Map
Validate parts is a non-empty List
Safely detect functionCall
Safely extract text using guarded lookup

These changes preserve existing functionality while improving resilience against malformed or unexpected API responses.

### Record

- [x] I agree to follow this project's Code of Conduct
- [x] I want to work on this issue

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.