{"record":{"id":"a316aae38efe4588","repo":"BerriAI/litellm","slug":"ref-must-be-a-non-empty-string","errorCode":null,"errorMessage":"ref must be a non-empty string","messagePattern":"ref must be a non-empty string","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/gitlab/gitlab_client.py","lineNumber":108,"sourceCode":"        self,\n        directory_path: str = \"\",\n        recursive: bool = False,\n        *,\n        ref: str | None = None,\n    ) -> str:\n        path_q: Final = f\"&path={quote(directory_path, safe='')}\" if directory_path else \"\"\n        rec_q: Final = \"&recursive=true\" if recursive else \"\"\n        ref_q: Final = quote(ref or self.ref, safe=\"\")\n        return f\"{self.base_url}/projects/{self._project_enc}/repository/tree?ref={ref_q}{path_q}{rec_q}\"\n\n    # ------------------------\n    # Public API\n    # ------------------------\n\n    def set_ref(self, ref: str) -> None:\n        \"\"\"Override the default ref (tag/branch) for subsequent calls.\"\"\"\n        if not ref:\n            raise ValueError(\"ref must be a non-empty string\")\n        self.ref = ref\n\n    def get_file_content(self, file_path: str, *, ref: str | None = None) -> str | None:\n        \"\"\"\n        Fetch the content of a file from the GitLab repository at the given ref\n        (tag, branch, or commit SHA). If `ref` is None, uses self.ref.\n\n        Strategy:\n          1) Try the RAW endpoint (returns bytes of the file)\n          2) Fallback to the JSON endpoint (returns base64-encoded content)\n\n        Returns:\n            File content as UTF-8 string, or None if file not found.\n        \"\"\"\n        raw_url: Final = self._file_raw_url(file_path, ref=ref)\n\n        try:\n            resp: Final = self.http_handler.get(raw_url, headers=self.headers)","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/integrations/gitlab/gitlab_client.py#L90-L126","documentation":"Raised by GitLabClient.set_ref when the ref argument is falsy (empty string or None after the type hint). set_ref overrides the default tag/branch used for subsequent API calls, and GitLab's repository endpoints require a non-empty ref parameter.","triggerScenarios":"Calling set_ref('') or set_ref(None) directly; passing a per-prompt git_ref read from config that was defined but left empty (git_ref: in YAML); computing a ref from a variable that is unset at runtime.","commonSituations":"Config templates that include a git_ref key for all prompts but leave it blank for default-branch prompts; scripts threading an optional ref through and passing the None default instead of skipping the call.","solutions":["Only call set_ref with a real tag, branch, or commit SHA; skip the call entirely when you want the configured default.","Guard callers: if git_ref: client.set_ref(git_ref).","Remove empty git_ref keys from config so the override path is never taken with a blank value."],"exampleFix":"# before\nclient.set_ref(os.getenv(\"PROMPT_GIT_REF\"))  # None when unset -> ValueError\n\n# after\nref = os.getenv(\"PROMPT_GIT_REF\")\nif ref:\n    client.set_ref(ref)","handlingStrategy":"type-guard","validationCode":"def apply_ref(client, ref: str | None) -> None:\n    if ref is not None and ref.strip():\n        client.set_ref(ref.strip())\n    # else: keep the configured default ref","typeGuard":"def is_usable_ref(ref: object) -> bool:\n    return isinstance(ref, str) and bool(ref.strip())","tryCatchPattern":null,"preventionTips":["Never call set_ref unconditionally with optional values; guard on truthiness.","Omit empty git_ref keys from config files entirely.","Unit-test the ref-resolution helper with None and '' inputs."],"tags":["gitlab","validation","api-misuse"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}