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
- 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
- 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
- Single encoding:
- Both
/rawand non-/rawendpoints 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.