Bug 505529

Summary: The handling of environment variables of startplasma-wayland is broken
Product: [Plasma] plasmashell Reporter: edinbruh <alvisebruniera>
Component: Startup processAssignee: Plasma Bugs List <plasma-bugs-null>
Status: REPORTED ---    
Severity: normal CC: dennis.lissov, jannik.glueckert, john.kizer, kde, kde, m.kurz, nate, sam
Priority: NOR    
Version First Reported In: 6.3.5   
Target Milestone: 1.0   
Platform: unspecified   
OS: Linux   
See Also: https://bugs.kde.org/show_bug.cgi?id=491579
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:

Description edinbruh 2025-06-12 15:49:19 UTC
SUMMARY

I recently had difficulties trying to configure my PATH variable in a shell/de-agnostic way, and did some digging into how plasma handles variables.

I might not be 100% correct (feel free to correct me), but here is how i understand it, and why I think it's broken. Also, this involves SDDM, not only plasma. I'm also not entirely sure this is the right place for this.

In a standard setup, SDDM runs the `wayland-session`  script which does some sourcing of /etc/profile and ~/.profile (or *sh-equivalent) than starts `startplasma-wayland`. 
`startplasma-wayland` used dbus to start the `plasma-core.target` systemd unit which depends on various other units.

Now, these services are started by the user's systemd session, they are not children of `startplasma-wayland`, which means they won't inherit it's environment. and they aren't even children of a single `plasma-core.target`, they only get the environment that systemd provides them. To escape this situation `startplasma-wayland` (before starting the target unit) uses dbus to add its variables to the user's systemd session's environment variables, which will then be inherited by all future user services (including plasma).

This is problematic because systemd already has a way for the user to configure environment variables for user services, which are environment generators (https://www.freedesktop.org/software/systemd/man/latest/systemd.environment-generator.html) and in particular systemd-environment-d-generator is especially useful (https://www.freedesktop.org/software/systemd/man/latest/systemd-environment-d-generator.html). The `startplasma-wayland` solution will override all variables that are present both in the profile sourced by `wayland-session` and the generator, this always includes the PATH variable which cannot be set from a generator, or it will be overwritten by plasma.

Moreover, these variables are inherited by all of the user's services, but only those that by chance started after plasma, so the user ends up with some services with an old variables, and some others with the overwritten ones.

A simple workaround that I'm employing is to add an `eval "$(systemctl --user show-environment)"` in the `wayland-session` script that fetches the user's systemd variables before the profile is sourced, so that both systemd and profile can modify the effective variables (i.e. adding paths to PATH). but this is not optimal because the profile can still override any variable and propagate it to any future user service.

Some better solutions might be (assuming we are already systemd dependant if we are using dbus to start plasma):
- dropping the `startplasma-wayland` script and reimplement its functionality as an environment generator
  - pro: profiles are always sourced, and systemd variables are always taken into account, the user can even decide the order of sourcing
  - con: still propagated to every user service
- have the plasma components source the profile, instead of `startplasma-wayland`
  - pro: less amount of work, nothing else needs to change
  - con: depending on the implementation the profile might be sourced multiple times
- have a plasma-environment-daemon that can be interrogated over dbus that sources/receives and holds all the variables (I personally like this one)
  - pro: variables are consistent, and limited to the plasma session (not all services)
  - con: another component to write and maintain

SOFTWARE/OS VERSIONS
Operating System: Fedora Linux 42
KDE Plasma Version: 6.3.5
KDE Frameworks Version: 6.14.0
Qt Version: 6.9.1
Kernel Version: 6.14.9-300.fc42.x86_64 (64-bit)
Graphics Platform: Wayland
Processors: 16 × AMD Ryzen 7 7700X 8-Core Processor
Memory: 30.9 GiB of RAM
Graphics Processor: AMD Radeon RX Vega
Comment 1 John Kizer 2025-06-20 04:24:32 UTC
Hello! You've reached the KDE bug tracker, which is for tracking and investigating specific bugs. Unfortunately I cannot pinpoint a specific user-facing bug that's being reported here. Can you please read https://community.kde.org/Get_Involved/Issue_Reporting and add more information here as requested in the bug report template, like Steps to Reproduce the issue you observed, what result you saw, and what result you expected?

If this is not a report of a specific user-facing bug, but instead a broader, general development proposal, then I'd recommend closing this bug report and posting as a topic at https://discuss.kde.org/ for discussion.

Thanks!
Comment 2 edinbruh 2025-06-26 14:17:15 UTC
(In reply to John Kizer from comment #1)
> Hello! You've reached the KDE bug tracker, which is for tracking and
> investigating specific bugs. Unfortunately I cannot pinpoint a specific
> user-facing bug that's being reported here. Can you please read
> https://community.kde.org/Get_Involved/Issue_Reporting and add more
> information here as requested in the bug report template, like Steps to
> Reproduce the issue you observed, what result you saw, and what result you
> expected?
> 
> If this is not a report of a specific user-facing bug, but instead a
> broader, general development proposal, then I'd recommend closing this bug
> report and posting as a topic at https://discuss.kde.org/ for discussion.
> 
> Thanks!

For me, I see this as a bug, so I'm adding the required info in this comment.

Steps to reproduce:
1. Try to edit the path in `~/.config/environment` adding `PATH=${PATH}:/path1`
2. Also add a fresh test variable `FOO=bar`
3. Edit the path in your profile (`~/.bashrc`, `~/.profile`, `/etc/profile`, doesn't matter) with `PATH=$PATH:/path2`
4. Also add a second fresh test variable `FIZZ=buzz`
5. Have some user service start at boot using `WantedBy=default.target` in its unit, for testing purpose
6. Reboot your system

Expected result:
* Plasma itself and applications should see:
    * either `PATH=$PATH:/path1:/path2` or `PATH=$PATH:/path2:/path1` (possibly the first)
    * `FOO=bar`
    * `FIZZ=buzz`
* All user services should see "at least":
    * `PATH=$PATH:/path1`
    * `FOO=bar`
* (Optionally, some user services may see the same variables as plasma)
    * This is to say that if some user services see more than the variable in `~/.config/environment` it's not a big deal

Observed result:
* Plasma itself and applications see:
    * `PATH=$PATH:/path2`
    * `FOO=bar`
    * `FIZZ=buzz`
* User services started before plasma see:
    * `PATH=$PATH:/path1`
    * `FOO=bar`
* User services started after plasma see:
    * `PATH=$PATH:/path2`
    * `FOO=bar`
    * `FIZZ=buzz`
Comment 3 John Kizer 2025-06-26 16:12:13 UTC
I'll have to defer to more experienced triagers/maintainers on whether this fits as a bug - FWIW it does seem like that procedure below differs from the recommended one at https://userbase.kde.org/Session_Environment_Variables
Comment 4 edinbruh 2025-06-26 17:53:10 UTC
(In reply to John Kizer from comment #3)
> I'll have to defer to more experienced triagers/maintainers on whether this
> fits as a bug - FWIW it does seem like that procedure below differs from the
> recommended one at https://userbase.kde.org/Session_Environment_Variables

Thanks for the quick reply.

To ease the triaging, I'll try to explain why I still think its a problem, despite having an explicitly recommended procedure.

Yes, it differs from that procedure, but it is still the procedure to globally set variables for systemd user services.
So if kde simply didn't get the variable from `~/.config/environment`, it would have been fine, just mildly annoying.
But because it actually messes up the variables for other services (as shown in the previous comment) I would still consider it a bug.

As such, because startplasma-wayland is already using systemd to start the user session, it would be nice if it didn't fight against systemd variables, but instead bought into the variable handling system. For example but not necessarily, like I explained in the summary.

Then, if the final user still wants to source their shell profile, they can still do it by adding a sourcing script as in the procedure you posted, instead of having the shell sourcing forced upon them by the administrator. Basically the whole thing just gives more control to the final user.

Moreover, the recommended procedure is nothing more than a kde specific sourcing path, which means that as soon as one changes DE, they have to port everything over, the same goes for sourcing the shell, as soon as the user changes shell they must do all over again. Instead, systemd is ubiquitous and DE agnostic. And even on systems without systemd, the init system will offer some way of setting up the environment. An even if everything fails, then the kde specific sourcing path is still a viable fallback.
Comment 5 Jannik Glückert 2025-11-11 21:35:46 UTC
I can confirm this issue, let me summarize why this is a real bummer:

Systemd provides various facilities for packages, system administrators, and users to customize the user env. Namely simple snippets in environment.d and env generators (used by flatpak, for example).

However, this is only active once the user session starts. startplasma-wayland, however, obviously starts outside of the session via sddm. This means that startplasma-wayland

If I understand https://invent.kde.org/plasma/plasma-workspace/-/blob/master/startkde/startplasma-wayland.cpp correctly, startplasma-wayland basically does:
1. eval plasma-workspace/env scripts
2. set some misc required env vars like XDG_SESSION_TYPE
3. export this env into the systemd session - roughly equivalent to `systemctl --user import-environment`
4. re-import the env from the systemd session, and use this for the desktop session

This is completely broken though. It means that the env that startplasma-wayland was launched with will always override env vars set through the standardized systemd mechanisms. Namely, we can't set PATH now, since the original startplasma-wayland env certainly has this set.

I think plasma should do something like:
1. set known constant envs in the systemd session (such as XDG_SESSION_TYPE)
2. import the systemd session.
3. run plasma-workspace/env scripts
4. export the updated env to the systemd session

For now, I'll just have to run plasma-workspace with this env export patched out :/
Comment 6 Jannik Glückert 2025-11-11 21:45:56 UTC
https://bugs.kde.org/show_bug.cgi?id=491579 has another (probably better) explanation of the current env procedure in startplasma