larksuite/cli · error

invalid %s %q: must be an absolute path to a PEM file

Error message

invalid %s %q: must be an absolute path to a PEM file

What it means

The extra root CA path (CLI_CA_PATH) is empty after trimming or is a relative path. For security, the CLI only accepts an absolute path to a PEM file so the trust anchor cannot be resolved ambiguously relative to the working directory. applyExtraRootCA rejects anything that is not absolute.

Source

Thrown at internal/transport/tls_ca.go:27

	"fmt"
	"net/http"
	"path/filepath"
	"strings"

	"github.com/larksuite/cli/internal/binding"
	"github.com/larksuite/cli/internal/envvars"
	"github.com/larksuite/cli/internal/vfs"
)

// applyExtraRootCA augments t with an additional PEM bundle used for configured proxy
// TLS interception.
func applyExtraRootCA(t *http.Transport, caPath string) error {
	caPath = strings.TrimSpace(caPath)
	if caPath == "" {
		return nil
	}
	if !filepath.IsAbs(caPath) {
		return fmt.Errorf("invalid %s %q: must be an absolute path to a PEM file", envvars.CliCAPath, caPath)
	}
	safeCAPath, err := binding.AssertSecurePath(binding.AuditParams{
		TargetPath:            caPath,
		Label:                 envvars.CliCAPath,
		AllowReadableByOthers: true,
	})
	if err != nil {
		return fmt.Errorf("unsafe %s %q: %w", envvars.CliCAPath, caPath, err)
	}
	pemBytes, err := vfs.ReadFile(safeCAPath)
	if err != nil {
		return fmt.Errorf("failed to read %s %q: %w", envvars.CliCAPath, caPath, err)
	}

	// Augment the system trust store. Do NOT silently discard a SystemCertPool
	// error: falling back to an empty pool would make this transport trust ONLY
	// the extra CA (dropping all system roots), which narrows trust unexpectedly
	// and could break TLS to legitimate endpoints. Fail closed instead.

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Set CLI_CA_PATH to an absolute path, e.g. /etc/ssl/certs/corp-ca.pem.
  2. Convert a relative path with an absolute prefix: use "$(pwd)/ca.pem" or realpath.
  3. Ensure the target is an actual PEM-encoded certificate file readable by the CLI user.

Example fix

// before
export LARKSUITE_CLI_CA_PATH="./certs/ca.pem"
// after
export LARKSUITE_CLI_CA_PATH="/etc/lark-cli/certs/ca.pem"
Defensive patterns

Strategy: validation

Validate before calling

p := strings.TrimSpace(os.Getenv("LARKSUITE_CLI_CA_PATH"))
if p != "" && !filepath.IsAbs(p) {
	return fmt.Errorf("CA path must be absolute: %s", p)
}

Prevention

When it happens

Trigger: Setting CLI_CA_PATH to something like 'certs/ca.pem' or './ca.pem' and starting the CLI; ApplyToTransport -> applyExtraRootCA performs filepath.IsAbs and fails.

Common situations: Relative path from internal docs or a colleague's setup where the working directory differed; CI runners executing from an unexpected cwd; value pointing to a directory or non-PEM file instead of the CA bundle.

Related errors


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