router-for-me/CLIProxyAPI · error

vertex credential: create directory failed: %w

Error message

vertex credential: create directory failed: %w

What it means

Returned by VertexCredentialStorage.SaveTokenToFile when os.MkdirAll on the parent of the auth file path fails (vertex_credentials.go:59-62). Analogous to the Kimi variant: the directory that should hold the vertex credential JSON cannot be created due to permissions, read-only filesystem, or a conflicting file along the path.

Source

Thrown at internal/auth/vertex/vertex_credentials.go:61

func (s *VertexCredentialStorage) SetMetadata(meta map[string]any) {
	s.Metadata = meta
}

// SaveTokenToFile writes the credential payload to the given file path in JSON format.
// It ensures the parent directory exists and logs the operation for transparency.
func (s *VertexCredentialStorage) SaveTokenToFile(authFilePath string) error {
	misc.LogSavingCredentials(authFilePath)
	if s == nil {
		return fmt.Errorf("vertex credential: storage is nil")
	}
	if s.ServiceAccount == nil {
		return fmt.Errorf("vertex credential: service account content is empty")
	}
	// Ensure we tag the file with the provider type.
	s.Type = "vertex"

	if err := os.MkdirAll(filepath.Dir(authFilePath), 0o700); err != nil {
		return fmt.Errorf("vertex credential: create directory failed: %w", err)
	}

	data, errMerge := misc.MergeMetadata(s, s.Metadata)
	if errMerge != nil {
		return fmt.Errorf("vertex credential: merge metadata failed: %w", errMerge)
	}

	f, err := os.Create(authFilePath)
	if err != nil {
		return fmt.Errorf("vertex credential: create file failed: %w", err)
	}
	defer func() {
		if errClose := f.Close(); errClose != nil {
			log.Errorf("vertex credential: failed to close file: %v", errClose)
		}
	}()
	enc := json.NewEncoder(f)
	enc.SetIndent("", "  ")

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Ensure the parent directory of the configured auth path exists and is writable: mkdir -p auths && chmod 700 auths
  2. Mount the auths volume read-write in the container
  3. Fix or remove conflicting files along the path (a file named like a directory component)

Example fix

# before
/app/auths: Read-only file system
# after (compose)
volumes: ["./auths:/app/auths"]
Defensive patterns

Strategy: validation

Validate before calling

dir := filepath.Dir(authFilePath)
if err := os.MkdirAll(dir, 0o700); err != nil {
    return fmt.Errorf("auth dir %q not creatable: %w", dir, err)
}

Try / catch

if err := s.SaveTokenToFile(path); err != nil && strings.Contains(err.Error(), "create directory failed") {
    log.Errorf("auth volume not writable: %s", filepath.Dir(path))
}

Prevention

When it happens

Trigger: auths directory on a read-only rootfs or volume; path component exists as a regular file; process user lacks write permission on the deepest existing directory.

Common situations: Kubernetes/Docker deployments not mounting auths/ writable; running as nobody against root-owned /app/auths; typos in a custom auth file path such as auths/vertex.json/extra.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/8c26e584aade8cee. Report an issue: GitHub.