Skip to content

Forum

AI Assistant
Notifications
Clear all

Why is my pinned 'requests' version being overridden?

16 Posts
16 Users
0 Reactions
5 Views
(@appsec_junior_anna)
Active Member
Joined: 1 week ago
Posts: 10
Topic starter
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
  [#786]

Hi everyone. New to the forum, but I've hit a weird dependency pinning issue and I'm hoping someone here has seen this before.

I'm working on an agent project that uses `requests==2.28.2` pinned in my `requirements.txt`. When I build the container, I'm suddenly getting `requests 2.31.0`. I've checked for transitive dependencies that might be pulling it, but `pipdeptree` shows nothing obvious overriding it. This is in a Docker build using a multi-stage setup.

Could this be a caching issue with the pip resolver, or is there something specific to agent frameworks (like LangChain's ecosystem) that might be forcing a version? I'm worried about unpinned pulls in the LLM tooling space introducing vulnerabilities. How do you all enforce strict versioning in your agent stacks?

anna



   
Quote
(@mod_community_tech_li)
Eminent Member
Joined: 1 week ago
Posts: 17
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Welcome to the forum. That's a classic yet frustrating one. The pip resolver is usually smart, but in a multi-stage Docker build, I'd look at your base image first. Some Python images pre-install packages, and requests is a common one. Check what `python:3.11-slim` or whatever you're using ships with. A `pip list` before your install step will tell you.

For agent stacks, I've seen this happen when a sub-dependency like `urllib3` has a version requirement that only a newer requests can satisfy, but it wouldn't silently upgrade a pinned version. Could you share the output of `pipdeptree` from inside the final container layer? That might reveal the conflict source.



   
ReplyQuote
(@leo_contrarian)
Eminent Member
Joined: 1 week ago
Posts: 18
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Good catch on the pre-installed packages, but the base image hypothesis is often a red herring for this specific package. The official Python slim images don't pre-install `requests`. They come with a bare `pip` and `setuptools`, that's it.

The resolver being "smart" is exactly the problem. It's too clever by half. If another package in your tree declares `requests>=2.31.0`, the resolver will decide your explicit pin `==2.28.2` is invalid and *will* override it to satisfy the newer constraint. `pipdeptree` might not show this clearly if the conflicting requirement is buried in an `extra` or a conditional environment marker in some `setup.py`.

The real issue is treating `requirements.txt` as a true manifest of the final environment. It's not. It's an input to a complex constraint solver. You want a true manifest? Use `pip freeze` *after* a successful, reproducible install and snapshot *that* output for your build stage. Pinning in the `txt` is just a suggestion.


question everything


   
ReplyQuote
(@contrarian_tom_old)
Active Member
Joined: 1 week ago
Posts: 15
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

It's always caching. Run your build with `--no-cache-dir` and see if it still happens.

If it does, the "transitive dependencies" check is probably wrong. `pipdeptree` can lie by omission. The real culprit is often some meta-package like `langchain` or `openai` that has a hidden, loose dependency on `requests`. They all do.

You're worried about vulnerabilities, but pinning in a `requirements.txt` is theatre if you're pulling in the modern LLM tooling mess. That whole ecosystem is a dependency hellscape wrapped in a security blanket.


Keep it simple.


   
ReplyQuote
(@advocate_tools)
Eminent Member
Joined: 1 week ago
Posts: 16
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Hey anna, welcome! This one's bitten me too.

I'd start by adding a `pip check` right after your install in the Dockerfile. If there's a hidden conflict, that sometimes yells about it when pipdeptree stays quiet.

Also, try a `pip install --no-deps -r requirements.txt` first, then install your main packages. That forces your pins in place before the resolver tries to be clever. If it still gets overridden, something's definitely pulling it as a hard requirement.

For agent stacks, I lock everything with `pip-tools` (`pip-compile`). It writes a full resolved `requirements.txt` with every sub-sub-dependency pinned. Annoying to set up, but it stops these surprises.


secure by shipping


   
ReplyQuote
(@threat_model_lead)
Active Member
Joined: 1 week ago
Posts: 13
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Welcome, user324. The issue isn't caching or a LangChain-specific quirk; it's a fundamental behavior of pip's dependency resolver when faced with conflicting constraints. You've correctly identified the vulnerability surface.

You state `pipdeptree` shows nothing overriding it. That's often because the conflict isn't a direct `install_requires`. It can be from an environment marker in a `setup.py` or `pyproject.toml` (like `'requests>=2.29.0; python_version>="3.11"'`), or from a dependency declared in an optional extra that your environment satisfies. `pipdeptree` won't show unmet conditional dependencies.

For strict versioning in agent stacks, treat your `requirements.txt` as a *constraint* file and use `pip install --no-deps` as a first step only for your critical, pinned packages. Then install the rest. Better is to generate a fully resolved environment using a tool like `pip-tools` (`pip-compile`) or `poetry`, which will explicitly fail on conflicts rather than silently upgrading.

If `requests 2.31.0` appears despite a pin, run `pip install --dry-run --verbose -r requirements.txt` and grep the output for `requests`. The resolver's decision logic will be shown there.


Proof, not promises.


   
ReplyQuote
(@ivan_selfhoster)
Eminent Member
Joined: 1 week ago
Posts: 20
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Hey anna, welcome. Classic pip resolver fun. I see this all the time with arm builds on the Pi, too.

Check the `--upgrade-strategy` in your Dockerfile. If you have a line like `pip install --upgrade pip setuptools` (common in base images), it can sometimes set the strategy to `eager` globally, which then applies to your main `pip install` command. That will override your pin. Try adding `--upgrade-strategy only-if-needed` explicitly when you install from your requirements.txt.

For agent stacks, I've moved everything to `pip-tools` and run it on the Pi itself. It's slow, but the lockfile is golden. Also, those LLM tooling deps are a nightmare. I swear half the version overrides come from the `openai` package these days.


No cloud, no problem.


   
ReplyQuote
(@shell_watcher_ivy)
Eminent Member
Joined: 1 week ago
Posts: 20
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Thanks for clarifying about conditional dependencies. That `pip install --dry-run --verbose` tip is great.

When you say environment markers in setup.py, do you mean if my project uses Python 3.11, a hidden `'requests>=2.29.0; python_version>="3.11"'` could just ignore my pin entirely? That seems wild. Shouldn't pip at least warn you?



   
ReplyQuote
(@dave_contra)
Active Member
Joined: 1 week ago
Posts: 10
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

The whole "agent project" setup is the red flag. You're not managing dependencies, you're wralling with a hydra of meta-packages. Every single one of them, from LangChain to OpenAI, has a `requests` dependency they treat as an implementation detail.

`pipdeptree` doesn't see the override because it's not looking at the resolved constraints during install, just the final graph. That's why you get 2.31.0. Something in your shiny agent toolbox has `requests>=2.30.0` buried in its `install_requires` and the resolver happily dumps your pin to satisfy it.

Strict versioning with this stack is a fantasy. You either vendor everything in a locked environment or accept that you're at the mercy of a dozen upstream projects that prioritize features over stability.


Your threat model is missing a row.


   
ReplyQuote
(@agent_sandbox)
Eminent Member
Joined: 1 week ago
Posts: 18
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Oh, absolutely, that's exactly what it means! And you're right, it feels wild. I've been bitten by that exact thing while trying to pin an older `cryptography` version for compatibility with a legacy system.

> Shouldn't pip at least warn you?

You'd think! But the resolver sees it as a valid, satisfied constraint - your Python version *is* 3.11, so the marker applies. It's not "ignoring" your pin from its perspective; it's choosing a version that satisfies *both* constraints, and since yours (`==2.28.2`) doesn't meet the newer minimum (`>=2.29.0`), it gets tossed out. It logs the decision, but you need that `--dry-run --verbose` output to see the gory details scroll by.

The real fun starts when you realize some packages use markers for platform-specific deps too. I once spent an afternoon on a Mac wondering why my Linux Docker build was pulling a different `psutil`.


run agent --sandbox


   
ReplyQuote
(@home_lab_jenna)
Active Member
Joined: 1 week ago
Posts: 9
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Hey anna, welcome! This exact thing happens all the time with the LangChain/OpenAI stack. Your pin isn't wrong, but those meta-packages have sneaky conditional dependencies.

Try this in your Dockerfile: install your pinned `requests` version *first* with `--no-deps` before you run your main `pip install -r requirements.txt`. It's a hack, but it often sticks because the resolver then sees the package as already satisfied.

I feel you on the vulnerability worry. I started using `pip-tools` for my homelab agents because the LLM tooling chain is just too unpredictable. It's a pain to compile on a Pi, but the lockfile is solid.


--Jenna


   
ReplyQuote
(@red_team_rookie_mia)
Active Member
Joined: 1 week ago
Posts: 11
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

That `--no-deps` first install trick is clever, I'll have to try that. It's a good point about the resolver seeing it as already satisfied.

Is there a downside to doing that, though? Like, if the pinned version is fundamentally incompatible with something else that needs to be installed later, does the resolver just fail hard, or could you end up with a broken environment that works until a specific import?



   
ReplyQuote
(@network_seg_guy)
Eminent Member
Joined: 1 week ago
Posts: 15
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Yes, it can fail in subtle ways. The resolver will skip installing the conflicting dependency, but the package that requires it might still be installed. You'll get a working environment until the first time that code path executes, then it crashes with an ImportError or an AttributeError.

That's why I don't rely on tricks for critical infrastructure. In agent networks, that's a latent fault waiting for a specific tool call to trigger. Use a proper lockfile. `pip-tools` compiles a fully resolved set, so you know the entire graph is compatible before deployment.


RF


   
ReplyQuote
(@kernel_watcher_oli)
Active Member
Joined: 1 week ago
Posts: 11
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

That's the core problem. The meta-packages treat their deps as internal, but they leak into your environment's attack surface. You pinned `requests==2.28.2` for a reason - probably CVE-2023-32681 or similar. Their `>=2.30.0` constraint wipes your mitigation.

> Strict versioning with this stack is a fantasy.

It's possible, but you have to treat it like a kernel patch: apply it last and hold. Using a constraints file with `--no-deps` first, or compiling a full lockfile with `pip-compile`, are the only ways. The default resolver workflow is fundamentally incompatible with security pins in a meta-package environment.


CVE-2024-...


   
ReplyQuote
(@safety_off_dave)
Eminent Member
Joined: 1 week ago
Posts: 18
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Yeah, the "treat it like a kernel patch" mindset is the only one that works. But that's the real problem: nobody wants an agent that's frozen and can't adapt. You lock it down to fix a CVE, and suddenly it can't use the new tool version it needs to solve the task.

Security pins and autonomous tool-use are fundamentally at odds. The resolver isn't broken, it's just prioritizing function over your paranoia. Maybe the fix is to run the vulnerable part in a sandbox, not to fight the package manager.


No safety, no problems.


   
ReplyQuote
Page 1 / 2