larksuite/cli · error

cannot expand ~: %w

Error message

cannot expand ~: %w

What it means

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.

Source

Thrown at internal/vfs/localfileio/path.go:260

// absolutize expands a leading ~/ to the user home directory and roots
// relative paths at cwd, exactly as this platform's own path rules would. The
// result is Cleaned but not symlink-resolved.
//
// Joining is decided by filepath.IsAbs alone, so the location computed here is
// the location the OS will actually open. A shape that only looks absolute
// under foreign rules (`C:\x` or `\x` on Unix) is a relative path here, and
// resolving it as such is what lets the denylist see through it — a cwd-local
// symlink named `C:` would otherwise carry it anywhere.
//
// raw is used as given: trailing and leading spaces are legal in filenames, so
// trimming them here would silently address a different file than the caller
// named (emptiness is screened separately, before this call).
func absolutize(raw, cwd string) (string, error) {
	p := raw
	if p == "~" || strings.HasPrefix(p, "~/") {
		home, err := trustedHome()
		if err != nil {
			return "", fmt.Errorf("cannot expand ~: %w", err)
		}
		p = filepath.Join(home, strings.TrimPrefix(p, "~"))
	}
	if !filepath.IsAbs(p) {
		p = filepath.Join(cwd, p)
	}
	return filepath.Clean(p), nil
}

// rejectForeignAbsolute refuses a path that is absolute only under another
// platform's rules. The strict tier rejects the shape outright rather than
// silently treating it as a relative name, which is a confusing way to grant
// access; the relaxed tier keeps such paths verbatim by contract and instead
// gets the denylist applied to the location the OS would really open.
func rejectForeignAbsolute(raw, flagName string) error {
	if isAbsolutePath(raw) && !filepath.IsAbs(raw) {
		return fmt.Errorf("%s %q is not a valid path on this platform", flagName, raw)
	}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Set the HOME environment variable before invoking the command.
  2. Replace the ~/... path with an explicit absolute path.
  3. Run the command as an interactive user with a home directory.

Example fix

// before
lark-cli drive upload --file ~/files/data.csv   # HOME not set
// after
HOME=/home/alice lark-cli drive upload --file ~/files/data.csv
Defensive patterns

Strategy: validation

Validate before calling

// Shell: fail fast if HOME is missing before any ~ path is used
: "${HOME:?HOME is not set; cannot use ~ paths}"

Prevention

When it happens

Trigger: 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.

Common situations: Cron jobs, systemd services, Docker containers, and CI workers where HOME is not set; Windows service accounts without a loaded profile.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/48bc203595994706. Report an issue: GitHub.