{"record":{"id":"48bc203595994706","repo":"larksuite/cli","slug":"cannot-expand-w","errorCode":null,"errorMessage":"cannot expand ~: %w","messagePattern":"cannot expand ~: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/vfs/localfileio/path.go","lineNumber":260,"sourceCode":"// absolutize expands a leading ~/ to the user home directory and roots\n// relative paths at cwd, exactly as this platform's own path rules would. The\n// result is Cleaned but not symlink-resolved.\n//\n// Joining is decided by filepath.IsAbs alone, so the location computed here is\n// the location the OS will actually open. A shape that only looks absolute\n// under foreign rules (`C:\\x` or `\\x` on Unix) is a relative path here, and\n// resolving it as such is what lets the denylist see through it — a cwd-local\n// symlink named `C:` would otherwise carry it anywhere.\n//\n// raw is used as given: trailing and leading spaces are legal in filenames, so\n// trimming them here would silently address a different file than the caller\n// named (emptiness is screened separately, before this call).\nfunc absolutize(raw, cwd string) (string, error) {\n\tp := raw\n\tif p == \"~\" || strings.HasPrefix(p, \"~/\") {\n\t\thome, err := trustedHome()\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"cannot expand ~: %w\", err)\n\t\t}\n\t\tp = filepath.Join(home, strings.TrimPrefix(p, \"~\"))\n\t}\n\tif !filepath.IsAbs(p) {\n\t\tp = filepath.Join(cwd, p)\n\t}\n\treturn filepath.Clean(p), nil\n}\n\n// rejectForeignAbsolute refuses a path that is absolute only under another\n// platform's rules. The strict tier rejects the shape outright rather than\n// silently treating it as a relative name, which is a confusing way to grant\n// access; the relaxed tier keeps such paths verbatim by contract and instead\n// gets the denylist applied to the location the OS would really open.\nfunc rejectForeignAbsolute(raw, flagName string) error {\n\tif isAbsolutePath(raw) && !filepath.IsAbs(raw) {\n\t\treturn fmt.Errorf(\"%s %q is not a valid path on this platform\", flagName, raw)\n\t}","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/vfs/localfileio/path.go#L242-L278","documentation":"This error is produced by `absolutize` when a path argument starts with `~` or `~/` but the user's home directory cannot be determined (via trustedHome). The tilde cannot be expanded, so the absolute location needed for policy checks cannot be computed. Unlike error 510, this is the raw inner error before the flag-name wrapper.","triggerScenarios":"Passing `~` or `~/...` to SafeInputPath/SafeOutputPath (or denyCheckLocalInput via LocalInputPath) when os.UserHomeDir fails: $HOME unset on Unix, no user profile on Windows, or running under a system account.","commonSituations":"Cron jobs, systemd services, Docker containers, and CI workers where HOME is not set; Windows service accounts without a loaded profile.","solutions":["Set the HOME environment variable before invoking the command.","Replace the ~/... path with an explicit absolute path.","Run the command as an interactive user with a home directory."],"exampleFix":"// before\nlark-cli drive upload --file ~/files/data.csv   # HOME not set\n// after\nHOME=/home/alice lark-cli drive upload --file ~/files/data.csv","handlingStrategy":"validation","validationCode":"// Shell: fail fast if HOME is missing before any ~ path is used\n: \"${HOME:?HOME is not set; cannot use ~ paths}\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set HOME explicitly in cron, systemd units, and Dockerfiles.","In service accounts on Windows, avoid ~ paths entirely; use absolute paths.","Document the HOME requirement next to any command using ~/files."],"tags":["go","home-directory","path-validation","environment"],"backgroundTag":"home-directory-unresolved","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}