Skip to content

Commit e9aa643

Browse files
fix(ci): match the action's full key normalization + add preflight
key length was 75 vs the working action's 73 — the prior strip removed only whitespace, leaving 2 stray chars (wrapping quotes or an OPENROUTER_API_KEY= prefix in the stored secret), so the Bearer token was wrong → 401. Use the action's exact _strip (whitespace + surrounding quotes) and drop a leading OPENROUTER_API_KEY= prefix. Add an OpenRouter /auth/key preflight so a bad key fails fast with the HTTP code instead of deep in the engine's retry loop. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 8e88d8c commit e9aa643

1 file changed

Lines changed: 21 additions & 12 deletions

File tree

.github/workflows/refresh-baseline.yml

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -128,22 +128,31 @@ jobs:
128128
RAW_AGENT_MODEL: ${{ secrets.AGENT_MODEL }}
129129
RAW_PARSING_MODEL: ${{ secrets.PARSING_MODEL }}
130130
run: |
131-
# Normalize like the review action's key prep: strip surrounding whitespace
132-
# (a trailing newline in the stored secret otherwise lands in the
133-
# Authorization header, which OpenRouter rejects as "Missing Authentication
134-
# header" — a 401 that looks like a bad key but is really a malformed header).
135-
_strip() { printf '%s' "$1" | tr -d '[:space:]'; }
136-
OPENROUTER_API_KEY="$(_strip "$RAW_OPENROUTER_API_KEY")"
137-
[ -n "$OPENROUTER_API_KEY" ] || { echo "::error::OPENROUTER_API_KEY secret is not set."; exit 1; }
138-
echo "::add-mask::$OPENROUTER_API_KEY"
139-
export OPENROUTER_API_KEY
140-
# Models may carry whitespace too; default to the OpenRouter cheap models
141-
# when unset (the engine also has its own defaults).
131+
# Normalize EXACTLY like the review action's key prep (action.yml). A raw
132+
# secret can carry surrounding whitespace/newlines, wrapping quotes, or a
133+
# leading "OPENROUTER_API_KEY=" prefix; any of those land in the
134+
# Authorization header and OpenRouter rejects it as "Missing Authentication
135+
# header" (a 401 that looks like a bad key but is a malformed header).
136+
# The previous fix stripped only whitespace, leaving quotes/prefix → still 401.
137+
_strip() { printf '%s' "$1" | tr -d '[:space:]' | sed -e 's/^"//;s/"$//' -e "s/^'//;s/'\$//"; }
138+
KEY="$(_strip "$RAW_OPENROUTER_API_KEY")"
139+
# Drop a leading "OPENROUTER_API_KEY=" if the secret was stored with it.
140+
case "$KEY" in OPENROUTER_API_KEY=*) KEY="${KEY#OPENROUTER_API_KEY=}";; esac
141+
KEY="$(_strip "$KEY")"
142+
[ -n "$KEY" ] || { echo "::error::OPENROUTER_API_KEY secret is not set."; exit 1; }
143+
echo "::add-mask::$KEY"
144+
export OPENROUTER_API_KEY="$KEY"
142145
AGENT_MODEL="$(_strip "$RAW_AGENT_MODEL")"
143146
PARSING_MODEL="$(_strip "$RAW_PARSING_MODEL")"
144147
export AGENT_MODEL="${AGENT_MODEL:-google/gemini-3-flash-preview}"
145148
export PARSING_MODEL="${PARSING_MODEL:-google/gemini-3.1-flash-lite-preview}"
146-
echo "Provider: openrouter; key length: ${#OPENROUTER_API_KEY}; agent_model: $AGENT_MODEL"
149+
echo "Provider: openrouter; key length: ${#OPENROUTER_API_KEY}"
150+
# Preflight the key against OpenRouter so a malformed/expired key fails here
151+
# with a clear message instead of deep inside the engine's retry loop.
152+
PRE=$(curl -sS -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $OPENROUTER_API_KEY" \
153+
--max-time 10 https://openrouter.ai/api/v1/auth/key || echo "curl-fail")
154+
echo "OpenRouter /auth/key preflight: HTTP $PRE"
155+
[ "$PRE" = "200" ] || { echo "::error::OpenRouter rejected the key (HTTP $PRE). Check the OPENROUTER_API_KEY secret value (no quotes/prefix/newline)."; exit 1; }
147156
mkdir -p "$OUT_DIR"
148157
# Run the same full-analysis path the review action uses for a base.
149158
uv run python "$ACTION_PATH/scripts/cb_engine.py" base \

0 commit comments

Comments
 (0)