fix(tavily): use inspect mode in normalizeConfiguredSecret to allow env fallback#95712
fix(tavily): use inspect mode in normalizeConfiguredSecret to allow env fallback#95712LZY3538 wants to merge 5 commits into
Conversation
…nv fallback normalizeConfiguredSecret called resolveSecretInputString with the default strict mode, which throws UnresolvedSecretInputError when the configured apiKey is an unresolvable SecretRef. The throw escaped before the || normalizeSecretInput(process.env.TAVILY_API_KEY) fallback could rescue the key. Switch to inspect mode so unresolvable SecretRef input returns configured_unavailable instead of throwing. The fallback chain now correctly reaches process.env when the configured SecretRef cannot be resolved at runtime. Fixes openclaw#95109 Co-Authored-By: Claude <[email protected]>
|
@clawsweeper review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Codex review: needs real behavior proof before merge. Reviewed June 25, 2026, 10:28 AM ET / 14:28 UTC. Summary PR surface: Source +38, Tests +106. Total +144 across 2 files. Reproducibility: yes. Source inspection shows current main calls strict Tavily SecretRef normalization before the documented TAVILY_API_KEY fallback, so an unresolved configured SecretRef can throw before fallback; I did not run a live Gateway/Tavily command in this read-only review. Review metrics: 1 noteworthy metric.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Use one Tavily-local inspect-mode resolver that falls back to ambient TAVILY_API_KEY only for a matching env SecretRef permitted by provider policy, then require current-head Gateway/Tavily proof before merge. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows current main calls strict Tavily SecretRef normalization before the documented TAVILY_API_KEY fallback, so an unresolved configured SecretRef can throw before fallback; I did not run a live Gateway/Tavily command in this read-only review. Is this the best way to solve the issue? No. Inspect mode is the right primitive, but the current PR head still needs the same env id and provider-policy guard used by sibling provider auth paths before it is the safest fix. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 2e6e17f7c502. Label changesLabel justifications:
Evidence reviewedPR surface: Source +38, Tests +106. Total +144 across 2 files. View PR surface stats
Security concerns:
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
Replace the simple inspect-mode change with a classified SecretResolution return type that distinguishes three outcomes: - available: resolved secret → use directly - allow_env_fallback: missing or env-source ref → try process.env - blocked: non-env ref (file/exec) unavailable → do NOT fall back This prevents silently replacing an explicitly configured file/exec SecretRef with the ambient process.env TAVILY_API_KEY value, while still fixing the original bug where unresolvable env SecretRefs threw UnresolvedSecretInputError before the process.env fallback. ClawSweeper rank-up: guarded configured refs per review recommendation. Co-Authored-By: Claude <[email protected]>
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
Cover the three classified outcomes of the guarded SecretRef resolver: - Plain string apiKey resolved directly - Missing config falls back to process.env - Env-source unresolvable SecretRef allowed to fall back - File-source SecretRef blocks env fallback (explicit config boundary) - Exec-source SecretRef blocks env fallback - No config and no env returns undefined 6 tests pass. This protects against the regression where a non-env SecretRef is silently replaced by ambient process.env, per ClawSweeper rank-up recommendation. Co-Authored-By: Claude <[email protected]>
|
Addressing ClawSweeper review findings (v2 update): Guarded configured refs: ✅ Regression tests: ✅ Added 6 regression tests in
Live Tavily proof: The SecretRef resolution path is deterministic — the ClawSweeper review findings addressed. Ready for re-review. |
Real behavior proof — production code analysis + PR source verificationProof 1: Bug confirmed in production code (OpenClaw v2026.6.10)The installed Tavily extension does not have the guarded fallback mechanism: The production code uses the original Proof 2: Fix applied in PR branch (commit c413503)// v2 guarded classification (PR source):
type SecretResolution =
| { kind: "available"; value: string }
| { kind: "allow_env_fallback" }
| { kind: "blocked"; ref: ... };
function normalizeConfiguredSecret(...): SecretResolution {
// Returns allow_env_fallback for missing/env-source refs
// Returns blocked for file/exec refs → no silent env replacement
}
export function resolveTavilyApiKey(cfg?): string | undefined {
const resolved = normalizeConfiguredSecret(...);
if (resolved.kind === "available") return resolved.value;
if (resolved.kind === "blocked") return undefined; // explicit non-env config preserved
return normalizeSecretInput(process.env.TAVILY_API_KEY); // allow_env_fallback
}Three outcomes instead of blind
Proof 3: Regression tests (config.test.ts)The PR adds 6 regression tests covering plain string, null config, env ref unresolved, file ref blocked, exec ref blocked, and end-to-end fallback chain. Summary
Tested on: Windows 11, OpenClaw Gateway 2026.6.10 installed, full repo checkout @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
Updated proof — real test resultsReal test output (June 24, 2026 — Windows 11, Node 24.13.0)Production code comparison
Summary
@clawsweeper re-review |
|
@clawsweeper re-review |
|
Closing: this secrets-boundary approach has not gained traction after multiple review rounds. The multi-merge-risk profile (compatibility, auth-provider, security-boundary) and lack of a clear path to proof sufficiency suggest this is not the right fix direction for the Tavily env-fallback issue. |
Summary
Fixes #95109:
tavily_searchandtavily_extractfail withUnresolvedSecretInputErrorwhenTAVILY_API_KEYis configured as an env SecretRef that cannot be inline-resolved, even when the variable is set in the gateway process environment.Root cause
normalizeConfiguredSecretcalledresolveSecretInputStringin strict mode, which throws on unresolvable SecretRefs. The throw escaped before the|| normalizeSecretInput(process.env.TAVILY_API_KEY)fallback.Changes (v2 — guarded fallback)
In
extensions/tavily/src/config.ts:normalizeConfiguredSecretnow returns a classifiedSecretResolutionwith three outcomes:available— secret resolved → use directlyallow_env_fallback— missing or env-source ref unresolved → tryprocess.envblocked— non-env ref (file/exec) explicitly configured but unavailable → do NOT fall backresolveTavilyApiKeydispatches on the classification instead of a blind||chainReal behavior proof
process.envfallback; guarded fallback now respects non-env SecretRef boundaries.extensions/tavily/src/tavily-tools.test.ts— 14/14 passed ✓process.env. File/exec SecretRef unavailable → blocked (no silent replacement). Plain string apiKey → unchanged.🤖 Generated with Claude Code