# Flutter: “‘_InternalLinkedHashMap<String, dynamic>’ is not a subtype of type ‘List<dynamic>’”

> _InternalLinkedHashMap or _Map<String, dynamic> is not a subtype of type List<dynamic>: the API sent an object, not a list. Read the list from the right key.

Canonical: https://app369.com/fix/flutter-internallinkedhashmap-is-not-a-subtype-of-type-list/
Last updated: 2026-11-08

Parsing an API response throws type ‘_InternalLinkedHashMap<String, dynamic>’ is not a subtype of type ‘List<dynamic>’ (newer Dart prints _Map<String, dynamic>). The code treats the decoded JSON as a list, but the server sent an object: often the list is wrapped in a key such as data or results, or the server returned an error object instead.

**Short answer**

Print response.body and look at the first character. If it is {, the top level is a map: read the list from its key, for example (json['data'] as List). Check the status code before parsing, because error responses are usually objects. Then map each item with fromJson.

## **Why the JSON isn’t the list you expected, and the fix**

1. 01 ### **The list is wrapped in an object**
  > “Unfortunately, jsonDecode() returns a dynamic, meaning that you do not know the types of the values until runtime.” [**Flutter, JSON and serialization**](https://docs.flutter.dev/data-and-backend/serialization/json) jsonDecode gives you whatever shape the server sent. Many APIs send {"data": [...], "page": 1}, which decodes to a Map; take the list out of it, then convert each item.```
final json = jsonDecode(response.body) as Map<String, dynamic>;
final items = (json['data'] as List)
    .map((e) => Product.fromJson(e as Map<String, dynamic>))
    .toList();
```
2. 02 ### **The server returned an error object**
  > “If the server does not return an OK response with a status code of 200, then throw an exception.” [**Flutter, Fetch data from the internet**](https://docs.flutter.dev/cookbook/networking/fetch-data) A 401, 404 or 500 usually comes back as {"error": "..."} even when the success response is a list. Check the status code first, so you parse only the shape you expect.```
if (response.statusCode != 200) {
  throw Exception('Request failed: ${response.statusCode} ${response.body}');
}
final list = jsonDecode(response.body) as List;
```
3. 03 ### **A single item where the model expects a list** An endpoint such as /products/42 returns one object. Use fromJson on the map directly instead of mapping over it, or call the list endpoint.```
final product = Product.fromJson(
  jsonDecode(response.body) as Map<String, dynamic>,
);
```

Checked against the vendor’s docs on November 8, 2026: [Flutter: JSON and serialization](https://docs.flutter.dev/data-and-backend/serialization/json); [Flutter cookbook: Fetch data from the internet](https://docs.flutter.dev/cookbook/networking/fetch-data).

## **Rather hand it over?**

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

- [from $450**App Fix Ticket**One reproducible bug in an existing mobile or web app, diagnosed and fixed.**See scope and start**](https://app369.com/fixed-price/flutter-firebase-bug-fix/)
- [from $450**AI-Built App Rescue**A Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.****No issues worth fixing, no charge.**** If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.**See scope and start**](https://app369.com/fixed-price/ai-app-rescue/)

Related: [**Flutter “type Null is not a subtype of type String”**](https://app369.com/fix/flutter-type-null-is-not-a-subtype-of-type-string/) · [**Flutter “SocketException: Failed host lookup”**](https://app369.com/fix/flutter-socketexception-failed-host-lookup/) · [**Flutter “Bad state: No element”**](https://app369.com/fix/flutter-bad-state-no-element/) · [**Flutter “Looking up a deactivated widget’s ancestor is unsafe”**](https://app369.com/fix/flutter-looking-up-a-deactivated-widgets-ancestor-is-unsafe/)

Questions

## **More on this error**

<details>

<summary>**It says List<dynamic> is not a subtype of Map<String, dynamic>. Same fix? **+</summary>

The mirror case: the server sent a list and the code expects one object. Cast to List and map each element with fromJson.

</details>

<details>

<summary>**What about List<dynamic> is not a subtype of List<String>? **+</summary>

jsonDecode makes every list a List<dynamic>. Convert it with List<String>.from(json['tags']) or (json['tags'] as List).cast<String>().

</details>

<details>

<summary>**Can you fix it for me? **+</summary>

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.

</details>

A different error?

## **Describe it and get a written quote**

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; Simon replies by email, usually within one business day.

[**Describe your problem **→](https://app369.com/contact/) [**All fixes**](https://app369.com/fix/)