{
  "id": 1077399,
  "title": "My CI Doesn't Know Which Free Model It's Calling Anymore",
  "url": "https://urgent.news/2026/08/15/my-ci-doesnt-know-which-free-model-its-calling-anymore",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-08-15T16:22:20.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/gitlab_3188/my-ci-doesnt-know-which-free-model-its-calling-anymore-4f2n"
  },
  "original_language": "en",
  "account": "On a Tuesday morning, my GitLab job failed. The error message reported a 404 status code for a missing /v1/chat/completions route. I inspected my codebase, but discovered no recent modifications. The free model route had shifted locations, while my YAML configuration continued referencing the outdated URL. The cause was not the model itself, but rather the way it was wired. I had inadvertently duplicated the same endpoint across multiple locations. Every time a provider altered a route, I was forced to manually edit YAML files, push changes, and wait for updates. This tedious process amounted to endpoint babysitting, not model engineering. To alleviate this issue, I employed a solution provided by MonkeyCode. Their service offers access to free model routes, along with a free server option. The sidecar component performs a single task: determining which model should be called by my jobs. Below is the Python code for the sidecar:\n\n```python\nimport json\nimport os\nfrom http.server import BaseHTTPRequestHandler, HTTPServer\n\nclass Handler(BaseHTTPRequestHandler):\ndef do_GET(self):\nif self.path == \"/config\":\nbody = json.dumps({\n\"base_url\": os.environ[\"MODEL_BASE_URL\"],\n\"model\": os.environ[\"MODEL_NAME\"],\n\"timeout_s\": int(os.environ.get(\"MODEL_TIMEOUT_S\", 20)),\n}).encode()\nself.send_response(200)\nself.send_header(\"Content-Type\", \"application/json\")\nself.end_headers()\nself.wfile.write(body)\nelif self.path == \"/healthz\":\nself.send_response(200)\nself.end_headers()\nself.wfile.write(b\"ok\")\nelse:\nself.send_response(404)\nself.end_headers()\n\nif __name__ == \"__main__\":\nport = int(os.environ.get(\"PORT\", 8000))\nHTTPServer((0.0.0.0, port), Handler).serve_forever()\n```\n\nThe sidecar's primary responsibility is to provide the current model endpoint. It does not store any tokens or request bodies. Its sole purpose is to act as a config shim, not a proxy. By introducing this sidecar, I simplified the CI process. The job now queries the sidecar for the model URL, rather than hardcoding it within the YAML configuration. The test cases ensure the sidecar's configuration adheres to the expected shape:\n\n```python\nimport os\nimport requests\n\nSIDECAR_URL = os.environ[\"MODEL_SIDECAR_URL\"]\n\ndef test_config_shape():\nr = requests.get(f\"{SIDECAR_URL}/config\", timeout=5)\nr.raise_for_status()\ndata = r.json()\nassert set(data.keys()) == {\"base_url\", \"model\", \"timeout_s\"}\nassert data[\"base_url\"].startswith(\"https://\")\nassert isinstance(data[\"model\"], str) and data[\"model\"]\nassert 1 <= data[\"timeout_s\"] <= 60\n```\n\nThe actual model-calling script remains unchanged:\n\n```python\nimport json, os, urllib.request\n\nurl = os.environ[\"MODEL_SIDECAR_URL\"]\ncfg = json.load(urllib.request.urlopen(f\"{url}/config\", timeout=5))\n```\n\nAdopting this approach over a YAML-based solution provides several advantages. The sidecar ensures a single point of configuration change, reducing the risk of inconsistencies across multiple locations. By separating the configuration logic from the model-calling script, the codebase remains cleaner and more maintainable. Additionally, the sidecar's lightweight nature minimizes the overhead on the CI pipeline, allowing for faster job execution.",
  "summary": "At 2:13 a.m. last Tuesday, my GitLab job went red. The stack trace ended with 404: /v1/chat/completions not found . I checked my code. Nothing had changed. The free model route had moved. My YAML still pointed at the old URL. The problem was never the model The model was fine. The weak point was the wiring. I had copied the same endpoint into too many places. Every time a provider rotated a…",
  "key_points": [
    "GitLab job failed due to 404 status code for missing /v1/chat/completions route",
    "Sidecar service resolves current model endpoint, eliminating endpoint babysitting",
    "Sidecar configuration test ensures proper baseurl, model, and timeouts"
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}