OpenAPITools / OpenAPITools/openapi-generator

[BUG] [DART-DIO] No serializer for 'Uint8List'

Open
#14,446 2 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

Bug Report Checklist
  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

Currently, I'm facing an issue passing a UInt8List to a generated API endpoint causes the following error:

DioError [DioErrorType.other]: Bad state: No serializer for 'Uint8List'.

See the schema below for the typing (string($binary). We are using over 30 other endpoints generated from our API docs so I'm quite confident that generation is working successfully. The issue seems specific to a UInt8List type.

openapi-generator version

OpenApiSpec 3.0.1; Generated from API docs
OpenApiGenerator 6.2.0

OpenAPI declaration file content or url

JSON schema:

"/api/application_logs": {
      "post": {
        "tags": [
          "Application"
        ],
        "summary": "Upload and process application logs.",
        "description": "The application logs and accompanying details.",
        "security": [
          {
            "OAuth2": []
          }
        ],
        "operationId": "uploadApplicationLogs",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "required": [
                  "application_version"
                ],
                "type": "object",
                "properties": {
                  "support_issue": {
                    "maxLength": 100,
                    "type": "string",
                    "description": "Type of the issue"
                  },
                  "support_message": {
                    "maxLength": 1000,
                    "type": "string",
                    "description": "Description of the issue"
                  },
                  "application_logs": {
                    "type": "string",
                    "description": "Zip file of the mobile app logs",
                    "format": "binary"
                  }
                },
                "example": {
                  "support_issue": "Issue type",
                  "support_message": "My app is not working...",
                  "application_logs": "..."
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Support request sent successfully",
            "content": {}
          },
          "400": {
            "description": "Bad format",
            "content": {}
          },
          "401": {
            "description": "Authentication failed",
            "content": {}
          },
          "500": {
            "description": "Internal error",
            "content": {}
          }
        },
        "x-codegen-request-body-name": ""
      }
    },

Generated Code

@BuiltValue()
abstract class UploadApplicationLogsRequest implements Built<UploadApplicationLogsRequest, UploadApplicationLogsRequestBuilder> {
  /// Type of the issue
  @BuiltValueField(wireName: r'support_issue')
  String? get supportIssue;

  /// Description of the issue
  @BuiltValueField(wireName: r'support_message')
  String? get supportMessage;

  /// Zip file of the mobile app logs
  @BuiltValueField(wireName: r'application_logs')
  Uint8List get applicationLogs;

  UploadApplicationLogsRequest._();

  factory UploadApplicationLogsRequest([void updates(UploadApplicationLogsRequestBuilder b)]) = _$UploadApplicationLogsRequest;

  @BuiltValueHook(initializeBuilder: true)
  static void _defaults(UploadApplicationLogsRequestBuilder b) => b;

  @BuiltValueSerializer(custom: true)
  static Serializer<UploadApplicationLogsRequest> get serializer => _$UploadApplicationLogsRequestSerializer();
}

class _$UploadApplicationLogsRequestSerializer implements PrimitiveSerializer<UploadApplicationLogsRequest> {
  @override
  final Iterable<Type> types = const [UploadApplicationLogsRequest, _$UploadApplicationLogsRequest];

  @override
  final String wireName = r'UploadApplicationLogsRequest';

  Iterable<Object?> _serializeProperties(
    Serializers serializers,
    UploadApplicationLogsRequest object, {
    FullType specifiedType = FullType.unspecified,
  }) sync* {
    if (object.supportIssue != null) {
      yield r'support_issue';
      yield serializers.serialize(
        object.supportIssue,
        specifiedType: const FullType(String),
      );
    }
    if (object.supportMessage != null) {
      yield r'support_message';
      yield serializers.serialize(
        object.supportMessage,
        specifiedType: const FullType(String),
      );
    }
    yield r'application_logs';
    yield serializers.serialize(
      object.applicationLogs,
      specifiedType: const FullType(Uint8List),
    );
  }

  @override
  Object serialize(
    Serializers serializers,
    UploadApplicationLogsRequest object, {
    FullType specifiedType = FullType.unspecified,
  }) {
    return _serializeProperties(serializers, object, specifiedType: specifiedType).toList();
  }
Generation Details

Dart-DIO

Steps to reproduce

Generate a scheme where it has a type string($binary)

Schema:

application_logs* | string($binary)Zip file of the mobile app logs
  1. Use request builder to assign data to request
  2. Invoke build method
  3. Pass to generated API endpoint
  4. Observe error is thrown
final requestBuilder = UploadApplicationLogsRequestBuilder();
      requestBuilder.supportIssue = issue;
      requestBuilder.supportMessage = message;
      requestBuilder.applicationLogs = logs;

      await _api.uploadApplicationLogs(
          uploadApplicationLogsRequest: requestBuilder.build());
Related issues/PRs

https://github.com/OpenAPITools/openapi-generator/issues/8429
https://github.com/OpenAPITools/openapi-generator/pull/13451

Suggest a fix

It seems related to serialization of Uint8List. The above related issues/PRs outline the addition of the function to the codebase.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure with the provided OpenAPI 3.0.1 schema using the Dart-DIO generator, then inspect the generated UploadApplicationLogsRequest serializer shown in the report. Compare the behavior with related issue 8429 and pull request 13451; done means a generated request containing string($binary) data serializes without the reported Uint8List error.

Written by the indexing model from the issue text.

Assessment

Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.