From 4f704a5dcd2393291d99f1b9340b1b262cdf9027 Mon Sep 17 00:00:00 2001 From: Terence Ong Date: Mon, 13 Apr 2026 08:48:32 +0700 Subject: [PATCH] fix: add key format validation to validate_credentials_detailed() Root cause of the 401 was a corrupted API key: the WordPress auth salt changed after the key was encrypted, so decryption produced garbage instead of sk-or-... OpenRouter interprets the garbled Bearer token as "Missing Authentication header." Adds the same sk-or- prefix check to the credential validation method so users see a clear "re-enter your key" message instead of a cryptic 401 error. Co-Authored-By: Claude Opus 4.6 --- .../providers/class-open-router-provider.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/includes/providers/class-open-router-provider.php b/includes/providers/class-open-router-provider.php index f89d9de..ce9b162 100644 --- a/includes/providers/class-open-router-provider.php +++ b/includes/providers/class-open-router-provider.php @@ -311,6 +311,22 @@ class PRAutoBlogger_OpenRouter_Provider implements PRAutoBlogger_LLM_Provider_In $key_prefix = substr( $api_key, 0, 6 ); $key_len = strlen( $api_key ); + if ( 0 !== strpos( $api_key, 'sk-or-' ) ) { + PRAutoBlogger_Logger::instance()->error( + sprintf( + 'API key format invalid (prefix="%s", len=%d). Likely salt changed — re-enter key.', + $key_prefix, + $key_len + ), + 'openrouter' + ); + return [ + 'status' => 'error', + 'message' => __( 'API key appears corrupted (decryption produced invalid data). Your WordPress auth salt may have changed. Please re-enter your OpenRouter API key in settings.', 'prautoblogger' ), + 'debug' => sprintf( 'bad_format:prefix=%s,len=%d', $key_prefix, $key_len ), + ]; + } + // Belt-and-suspenders: inject Authorization at cURL level (see send_chat_completion). $auth_header_value = 'Bearer ' . $api_key; $curl_auth_filter_cred = function ( $handle, $parsed_args, $url ) use ( $auth_header_value ): void {