GitLab API returns 400 Bad Request when accessing files in subdirectories

After upgrading to the latest GitLab version (possibly two versions ago), the Repository Files API endpoint returns HTTP 400 errors when trying to access any file located in a subdirectory, regardless of whether the filename or path contains dots or special characters. Files at the repository root work correctly. This worked before the update.

Steps to reproduce

  1. Access a file at repository root (works correctly):
curl -v --header "PRIVATE-TOKEN: glpat-xxxxxxxxxxxxxxxxxxxx" \
  "https://gitlab.example.com/api/v4/projects/123/repository/files/README.md/raw?ref=main"

Result: HTTP 200 - File content returned successfully

  1. Access any file in a subdirectory (fails):
curl -v --header "PRIVATE-TOKEN: glpat-xxxxxxxxxxxxxxxxxxxx" \
  "https://gitlab.example.com/api/v4/projects/123/repository/files/folder%2Ffile.txt/raw?ref=main"

Result: HTTP 400 Bad Request with empty response body

Expected behavior

The API should return the file content with HTTP 200 for files in subdirectories, as it did before the update.​

Actual behavior

HTTP 400 Bad Request is returned with empty response body for any file path containing subdirectories (URL-encoded slashes as %2F).

Additional context

  • Files at repository root work correctly via the same API endpoint
  • ANY file in a subdirectory fails, regardless of filename (tested with and without dots in the name)
  • The issue appears after a recent GitLab update
  • Tried various encoding methods:
    • Single encoding: folder%2Ffile.txt → 400 error
    • Double encoding: folder%252Ffile.txt → 400 error
    • Encoding dots: folder%2Ffile%2Etxt → 400 error
  • Both /raw and non-/raw endpoints return 400 for subdirectory paths
  • Authentication is confirmed working (root-level files succeed)
  • Project ID, branch name, and file paths are verified correct

Environment

  • Self-hosted GitLab version: 18.8.1
  • API endpoint: /api/v4/projects/{id}/repository/files/{file_path}/raw
  • Authentication method: Private Token (PRIVATE-TOKEN header)

Regression

This appears to be a regression in URL path parsing for the Repository Files API, specifically affecting the handling of URL-encoded slashes (%2F) in file paths.

Edited by 🤖 GitLab Bot 🤖