router-for-me/CLIProxyAPI · error

failed to update source auth file: %w

Error message

failed to update source auth file: %w

What it means

setSourceAuthFileDisabled failed while reading, parsing, or writing the plugin source auth file to flip its disabled flag, and the error was not os.IsNotExist. The %w wrap carries the real fs error — typically a permission failure on read or on the 0600 write, or a read-only filesystem issue.

Source

Thrown at internal/api/handlers/management/auth_files_fields.go:134

// patchPluginVirtualSourceStatus toggles disabled on a plugin multi-auth source file and all
// runtime auths expanded from it. Virtual project children cannot be toggled independently.
func (h *Handler) patchPluginVirtualSourceStatus(ctx context.Context, targetAuth *coreauth.Auth, disabled bool) error {
	if h == nil || h.authManager == nil || targetAuth == nil {
		return fmt.Errorf("core auth manager unavailable")
	}
	sourcePath := strings.TrimSpace(authAttribute(targetAuth, coreauth.AttributeVirtualSource))
	if sourcePath == "" {
		sourcePath = strings.TrimSpace(authAttribute(targetAuth, "path"))
	}
	if sourcePath == "" {
		return errPluginVirtualAuth
	}
	if errWrite := setSourceAuthFileDisabled(sourcePath, disabled); errWrite != nil {
		if os.IsNotExist(errWrite) {
			return errAuthFileNotFound
		}
		return fmt.Errorf("failed to update source auth file: %w", errWrite)
	}
	now := time.Now()
	for _, auth := range h.authManager.List() {
		if auth == nil {
			continue
		}
		if !sameAuthFilePath(authAttribute(auth, "path"), sourcePath) &&
			!sameAuthFilePath(authAttribute(auth, coreauth.AttributeVirtualSource), sourcePath) {
			continue
		}
		applyAuthDisabledState(auth, disabled)
		auth.UpdatedAt = now
		if _, errUpdate := h.authManager.Update(ctx, auth); errUpdate != nil {
			return fmt.Errorf("failed to update auth %s: %w", auth.ID, errUpdate)
		}
	}
	return nil
}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Check the wrapped cause: permission denied → chown/chmod the file and auth dir for the service user
  2. If the auth dir is mounted read-only, remount it rw or point auth-dir at a writable location
  3. Verify disk space and filesystem health (df -h, dmesg for I/O errors)
  4. Retry the PATCH after fixing the underlying fs issue

Example fix

# before
docker run -v ./auths:/app/auths:ro ...
# after
docker run -v ./auths:/app/auths rw, after chown -R appuser:appuser ./auths
Defensive patterns

Strategy: try-catch

Validate before calling

if info, err := os.Stat(sourcePath); err != nil {
    return err
} else if info.Mode().Perm()&0o200 == 0 {
    return errors.New("auth file not writable")
}

Try / catch

if err := patchPluginVirtualSourceStatus(ctx, auth, disabled); err != nil {
    if os.IsPermission(errors.Unwrap(err)) { /* fix ownership, then retry once */ }
    return err
}

Prevention

When it happens

Trigger: PATCH toggle of a plugin multi-auth source where the file or its directory is read-only or owned by another user; auth dir mounted read-only (container volume with wrong mode); disk full causing the write to fail; SELinux/AppArmor denying the write.

Common situations: Running the proxy in Docker with a bind-mounted auths/ volume owned by root while the process runs non-root; a hardened or immutable container filesystem; files created by a previously different service user.

Related errors


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