Skip to content

Response schema rejects valid GitLab responses — *_access_levels[].user_id/.group_id and commit are non-nullable but GitLab returns null #575

Description

@prosomoalexd

Summary

Several tools fail with Zod validation errors on well-formed GitLab API responses. The response schemas mark fields as non-nullable that GitLab legitimately returns as null, so valid responses are rejected before reaching the caller. For protect_branch this is worse: the mutation is applied server-side, then the response fails to parse — so a successful write surfaces as an error.

Affected tools

  • list_protected_branches
  • protect_branch
  • get_branch_diffs

(and any tool sharing the protected-branch access-level or branch-diff commit schemas)

Environment

  • GitLab.com REST API
  • Response validation via Zod
  • Triggered with role-based protected-branch access levels (e.g. "Maintainers"), not user-/group-specific ones

Steps to reproduce

  1. Protect a branch using a role-based push/merge access level (e.g. Maintainers) rather than a specific user or group.
  2. Call list_protected_branches (or protect_branch on that branch).
  3. Separately, call get_branch_diffs over a range where GitLab returns a null commit field (e.g. an empty/no-op range).

Actual behavior

list_protected_branches:

Invalid arguments: 0.push_access_levels.0.user_id: Expected number, received null,
0.push_access_levels.0.group_id: Expected number, received null ...

protect_branch(develop) — same error, but the protection was actually applied (a subsequent list_branches shows protected: true):

Invalid arguments: 0.push_access_levels.0.user_id: Expected number, received null ...

get_branch_diffs(from=<feature-branch>, to=develop):

Invalid arguments: commit: Expected object, received null

Root cause: GitLab returns null for user_id/group_id on role-based access levels (only user-/group-specific levels populate them), and can return a null commit on branch-diff responses — but the schema marks these non-nullable.

Impact

  • Blocks reading protected-branch state and branch diffs entirely.
  • Makes protected-branch writes look failed after they have already applied — inviting duplicate/retry attempts.
  • Not workflow-specific: affects every consumer of these tools.

Expected behavior

Valid GitLab responses parse successfully. In particular:

  • *_access_levels[].user_id and *_access_levels[].group_id accept null.
  • The branch-diff commit field accepts null.
  • A successful write (e.g. protect_branch) returns the applied object rather than surfacing a parse error.

Suggested fix

  • Make the affected response fields nullable/optional in their Zod schemas: push_access_levels[].user_id, push_access_levels[].group_id, merge_access_levels[].user_id, merge_access_levels[].group_id, and the nullable commit field(s) in branch-diff responses.
  • Audit sibling response schemas for the same over-strict pattern (any *_id or nested object GitLab may return as null/absent).
  • Ensure write endpoints return the applied object on success so a clean mutation never surfaces as an error.

Severity

Medium — blocks reads of protected-branch/diff state and makes applied writes look failed; manual workarounds exist (list_branches to confirm a write; create_merge_request + get_merge_request to assess a diff).


Filing this as an FYI so it's on your radar — I'm a user, not able to
contribute a PR or commit to ongoing back-and-forth. Please triage/close
as you see fit; no need to wait on me.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions