fix(docker): expand ~ and $VAR in extra_mounts destinations - #128
Draft
bai-uipath wants to merge 1 commit into
Draft
fix(docker): expand ~ and $VAR in extra_mounts destinations#128bai-uipath wants to merge 1 commit into
bai-uipath wants to merge 1 commit into
Conversation
The source side of an extra_mounts spec is normalized with expandvars(expanduser(...)) so authors can write portable specs; the destination was only checked for a leading "/" and never expanded. That asymmetry makes one common mount impossible to write portably. env_passthrough forwards HOME with the HOST value on purpose, so any container-side path that must line up with $HOME -- $HOME/.uipath for the uip CLI's saved login state, for instance -- has a different literal value on every host. The only way to express it was to hardcode one host's home directory, which then mounts to the wrong place everywhere else. A login state the CLI cannot see fails tasks as a capability problem rather than a config one, so the misconfiguration is close to invisible: it cost 26% of the rows in an ad-hoc Maestro run before it was spotted. Expand the destination the same way, before the absolute-path check, so `~/.uipath:$HOME/.uipath:rw` resolves. Two details worth keeping: - expandvars leaves an unset variable verbatim, so a typo'd name still fails the absolute-path check. The message now shows the raw and the expanded form, otherwise it reads as a puzzle. - the framework-owned-mount check runs on the expanded destination, since a variable could itself expand to /work or / and the raw form would sail past the gate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
extra_mountsexpands~and$VARon the source side of a spec but not on the destination, which was only checked for a leading/. This expands the destination the same way, before the absolute-path check.Why: the Maestro flow v2 preview evals need it
The concrete driver is evaluating the
preview/uipath-maestro-{flow,case,bpmn}builder-SDK skills (flow v2, the@uipath/flow-sdkTypeScript authoring path) under the docker driver. Those runs need two things the shipped v1 experiments never had to mount by hand.The
uipCLI login state is the first one. Almost every Maestro task ends in a tenant call, so the container needs the saved credential at~/.uipath. CI sidesteps this withUIPATH_CLI_ENABLE_ENV_AUTHand a token in the environment, but the eval VM and any dev box authenticate from the file, so the overlay has to mount it. The destination cannot be/root/.uipath: the docker runner forwards--env HOMEwith the host value by design (models/sandbox.py, "HOME is intentional in default"), which overrides the image's/root, anduipthen looks under that forwarded host home. So the destination has to be the host's$HOME/.uipath, and until this change the only way to write that was to hardcode one machine's home directory.The skills repo root is the second one. A v1 experiment gets it mounted for free, because its
plugins.pathis the repo root and plugin paths are auto-mounted. A preview experiment narrows the catalog topreview/, which drops the mount, and criteria across the flow and case suites shell out to$SKILLS_REPO_PATH/tests/tasks/**/_shared/*.py. Adding it back also wants$VARon both sides.Why the failure mode is worth a code change rather than a comment
A login state the CLI cannot see fails tasks on their tenant calls, which scores as a capability problem, not a configuration one, so the run completes and reports a plausible-looking number. A manual
docker rundoes not reproduce it either: without--env HOMEthe container falls back to the image's/rootand authenticates fine. The 2026-08-20 preview run only came out clean (auth-failure signatures at zero across all 257 rows) because the destination was pointed at the forwarded host home first.The hardcode is already in the tree, which is the other reason to fix it upstream rather than work around it again.
skills/tests/experiments/same-ground-headtohead.yamlmounts to/home/tmatup/.uipath, with a comment saying the destination "must match that path until #100 makes HOME portable". This is that change; #100 is the issue it closes. Two lines in that overlay become$HOME/...once this merges, and it stops carrying one person's home directory.Downstream
UiPath/skills#2728adds the preview docker overlay and currently ships the auth mount commented out, with a literal-home fallback documented, because a$HOMEdestination fails validation outright on 0.10.2. That comment can be deleted and the mount enabled once this is released.Notes
Two details are deliberate rather than incidental:
expandvarsleaves an unset variable verbatim, so a typo'd name still fails the absolute-path check. The message now shows the raw and the expanded form, otherwise it reads as a puzzle./workor/and the raw form would sail past the gate.Four tests cover destination
$VAR, destination~, the unset-variable rejection, and a variable expanding to a reserved destination.🤖 Generated with Claude Code