Skip to content

repoGetContents returns different types causing JSON deserialization errors in generated Swagger SDKs #34820

Closed
@rickyma

Description

@rickyma

Description

GitHub Issue Description

Title:

API inconsistency: /repos/{owner}/{repo}/contents/{filepath} returns different types causing JSON deserialization errors in generated SDKs

Problem Description:

The Gitea API endpoint /repos/{owner}/{repo}/contents/{filepath} has an inconsistent response format that causes JSON deserialization errors in generated SDKs (especially Java):

  • When filepath is a file: Returns a single ContentsResponse object {}
  • When filepath is a directory: Returns an array of ContentsResponse objects []

This inconsistency leads to:

  1. SDK Generation Issues: OpenAPI generators cannot properly handle union types, causing incorrect client code generation
  2. Runtime Errors: Java SDK throws JsonSyntaxException: Expected BEGIN_OBJECT but was BEGIN_ARRAY when requesting directory contents
  3. Poor Developer Experience: Developers need to handle two different response formats for the same endpoint

Error log:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:397)
	at com.google.gson.Gson.fromJson(Gson.java:1227)
	at com.google.gson.Gson.fromJson(Gson.java:1137)
	at com.google.gson.Gson.fromJson(Gson.java:1047)
	at com.google.gson.Gson.fromJson(Gson.java:1014)
	at io.gitea.client.JSON.deserialize(JSON.java:134)
	at io.gitea.client.ApiClient.deserialize(ApiClient.java:718)
	at io.gitea.client.ApiClient.handleResponse(ApiClient.java:921)
	at io.gitea.client.ApiClient.execute(ApiClient.java:848)
	at io.gitea.api.RepositoryApi.repoGetContentsWithHttpInfo(RepositoryApi.java:14365)
	at io.gitea.api.RepositoryApi.repoGetContents(RepositoryApi.java:14348)

Current Behavior:

# File request - returns object
GET /api/v1/repos/owner/repo/contents/file.txt
{"name": "file.txt", "type": "file", ...}

# Directory request - returns array  
GET /api/v1/repos/owner/repo/contents/directory
[{"name": "file1.txt", "type": "file", ...}, {"name": "file2.txt", "type": "file", ...}]

Expected Behavior:

The API should consistently return an array format for both files and directories:

# File request - returns array with single element
GET /api/v1/repos/owner/repo/contents/file.txt
[{"name": "file.txt", "type": "file", ...}]

# Directory request - returns array (unchanged)
GET /api/v1/repos/owner/repo/contents/directory  
[{"name": "file1.txt", "type": "file", ...}, {"name": "file2.txt", "type": "file", ...}]

Proposed Solution:

  1. Modify GetContentsOrList function in services/repository/files/content.go to always return []*api.ContentsResponse instead of any
  2. Update Swagger definition in templates/swagger/v1_json.tmpl to consistently reference ContentsListResponse
  3. Update API documentation to reflect the consistent array response format
  4. Update test cases to expect array format for file requests

Benefits:

  • Consistent API behavior across all request types
  • Better SDK generation for all programming languages
  • Backward compatible - existing clients can simply access response[0] for file content
  • Follows RESTful conventions - collection endpoints should return arrays

Files to be modified:

  • services/repository/files/content.go
  • templates/swagger/v1_json.tmpl
  • routers/api/v1/repo/file.go (Swagger comments)
  • services/repository/files/content_test.go (test cases)

This change would align Gitea's API with GitHub's API behavior and resolve SDK generation issues across multiple programming languages.

Gitea Version

latest

Can you reproduce the bug on the Gitea demo site?

Yes

Log Gist

No response

Screenshots

No response

Git Version

No response

Operating System

No response

How are you running Gitea?

./gitea web

Use auto-generated Java SDK:

wget https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.68/swagger-codegen-cli-3.0.68.jar

java -jar swagger-codegen-cli-3.0.68.jar generate \
  -i http://127.0.0.1:8080/swagger.v1.json \
  -l java \
  -o gitea-java-client \
  --api-package io.gitea.api \
  --model-package io.gitea.model \
  --invoker-package io.gitea.client \
  --group-id io.gitea \
  --artifact-id gitea-java-client \
  --artifact-version 1.0.0

Database

None

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions