Environment isn't updated when changes are made to watch_files returned by plugins
#8603
Unanswered
rpendleton
asked this question in
Troubleshooting and bug reports
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Problem
When an environment plugin returns
watch_files, changes to those watched files don't trigger an environment update in the current shell. You have tocdaway and back for the changes to take effect. If you haveenv_cacheenabled, you also have to runmise cache clearbefore leaving and returning to the current directory.In my case, I'm seeing this behavior with
mise-env-fnox. Given that the plugin relies onfnox config-filesto determine itswatch_filesand that the output of that command looks correct, I'd assume the correct files are making it back to mise. However, after modifying a value viafnox set KEY VALUE, the new value isn't reflected in the shell environment until I leave and re-enter the directory.By contrast, changes made using
mise set KEY=VALUEare reflected immediately.Output from `mise doctor`
Analysis
hook-envruns on each prompt. The relevant steps are:should_exit_early_fast) — runs before anything is loaded. Compares mtimes of file paths inPREV_SESSION.watch_filesagainst the session'slatest_updatetimestamp. Exits early if nothing changed.tools=falseplugins execute — as a side effect of config loading / assembling watch_files for the slow path.should_exit_early) — checks watch_files fromconfig.watch_files(). Exits early if nothing changed.tools=trueplugins execute — duringload_post_env()insidefinal_env().When considering plugin-returned
watch_files, there's a few problems in that process:PREV_SESSION.watch_filesnever includes plugin watch_files, because they were never stored in the session. It exits early and plugins never run. This is true regardless of whether the plugin istools=trueortools=false.config.watch_files()chainsenv_files,env_scripts, and tera files — but notenv_results.watch_files. Technically, though, that would only cover thetools=falsecase, since it hasn't executedtools=trueyet.env_with_path_and_split()doesn't return watch_files to the caller, soHookEnv::run()can't include them when building the session.save_env_cache_split()only receivesEnvResultsfromload_post_env()(ToolsOnly), sotools=falseplugin watch_files aren't included inCachedEnv. The non-tool cache (CachedNonToolEnv) does track them and properly invalidates — causing the plugin to re-execute — butCachedEnvstill considers itself valid and returns the stale full environment, discarding the fresh plugin results.Potential fixes
There are two related problems to solve: (1) getting plugin watch_files into the session so the fast and slow paths can detect changes, and (2) getting
tools=falseplugin watch_files intoCachedEnvso it properly invalidates. Several changes are needed for complete coverage:config.watch_files()could chainenv_results.watch_filesalongsideenv_filesandenv_scripts. Sinceconfig.watch_files()usesNonToolsOnlyenv_results, this coverstools=falseplugins only. However,config.watch_files()feeds both the slow-path check andbuild_session(), so this single change getstools=falseplugin watch_files into both the slow path and the session (and thus the next prompt's fast path).env_with_path_and_split()could return the post-envenv_results.watch_filesso thatHookEnv::run()can merge them into the session's watch_files. On the non-cached path, these come fromfinal_env()which runsload_post_env()withToolsOnly, so this coverstools=trueplugins. On a cache hit,CachedEnv.watch_filesalready has them from the previous run. Sincetools=truewatch_files aren't available until after env computation, they can't help with the slow-path check on the current prompt — but once in the session, they'll be checked by the fast path on the next prompt.The slow-path check could extend its watch_files with
PREV_SESSION.watch_filesbefore checking. This bridges the gap fortools=trueplugins: their watch_files from the previous session would be checked in the slow path even beforeload_post_envruns in the current prompt. The fast path already readsPREV_SESSION.watch_files, so this makes the slow path consistent. Requires makingHookEnvSession.watch_filespub and passing it toshould_exit_early().final_env()could merge theNonToolsOnlywatch_files into theToolsOnlyenv_resultsbefore returning. This ensuressave_env_cache_split()includestools=falsewatch_files inCachedEnv, so changes to those files properly invalidate the full env cache. TheNonToolsOnlyresults are available viaconfig.env_results_cached(), though care is needed to ensure they've been populated before this point (i.e.,config.env_results()must have been called first).From my testing, all of these might be needed for complete coverage, but I'm not very familiar with how mise works so I figured I'd open a discussion instead of a PR.
Potential Patch
I'm not familiar with mise or Rust, but working through this issue with Claude Code led to the following.
Potential patch
Beta Was this translation helpful? Give feedback.
All reactions