openclaw - 💡(How to fix) Fix Bug: `cred.key?.trim is not a function` crash after upgrading to 2026.3.31 — env ref auth profiles not fully supported in credential resolution [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#58913Fetched 2026-04-08 02:31:16
View on GitHub
Comments
0
Participants
1
Timeline
2
Reactions
0
Participants
Timeline (top)
closed ×1locked ×1

Error Message

``` openclaw logs --follow\n\n[plugins] matrix: ... (normal)\nAgent failed before reply: cred.key?.trim is not a function ```


Labels: bug, auth, regression, credential-management

Root Cause

In `./dist/models-config-KyFi5MCD.js` (line ~277), the `resolveApiKeyFromCredential(cred)` function handles auth profile credentials like this:

```js function resolveApiKeyFromCredential(cred, env = process.env) { if (cred.type === "api_key") { const keyRef = coerceSecretRef(cred.keyRef); if (keyRef && keyRef.id.trim()) { // env-ref or non-env-ref resolution ... } // FALLBACK — this line crashes when cred.key is not a string: if (cred.key?.trim()) return { apiKey: cred.key, source: "plaintext", discoveryApiKey: toDiscoveryApiKey(cred.key) }; return; } ... } ```

With the new env secret ref format, when a credential profile has:

  • `keyRef` set to a valid ref → the first `if` branch is entered correctly
  • BUT if the profile was somehow migrated/normalized such that `cred.key` itself became a ref object (e.g. `{ source: "env", id: "SOME_VAR" }`) rather than plain text, the fallback line `cred.key?.trim()` throws because objects have no `.trim()`.

It could also happen when:\n- The auth profile format changes between versions and old `key: { ... }` objects remain in the credential store, while previously `key` was always a string

  • The profile store or migration logic writes an object to `cred.key` instead of moving it to `cred.keyRef`

Fix Action

Fix / Workaround

  1. Run openclaw 2026.3.28 with auth profiles that may contain non-plaintext key values
  2. Upgrade to openclaw 2026.3.31\n3. Trigger any model call (e.g. send a message)\n4. Observe `cred.key?.trim is not a function` error
RAW_BUFFERClick to expand / collapse

Bug Report

Describe the bug

After upgrading from 2026.3.28 to 2026.3.31 (which introduced improved env-based secret ref support for model auth profiles), all model-based replies fail with:

``` Agent failed before reply: cred.key?.trim is not a function ```

The error occurs for every model profile — none of them can resolve their API key.

Root cause

In `./dist/models-config-KyFi5MCD.js` (line ~277), the `resolveApiKeyFromCredential(cred)` function handles auth profile credentials like this:

```js function resolveApiKeyFromCredential(cred, env = process.env) { if (cred.type === "api_key") { const keyRef = coerceSecretRef(cred.keyRef); if (keyRef && keyRef.id.trim()) { // env-ref or non-env-ref resolution ... } // FALLBACK — this line crashes when cred.key is not a string: if (cred.key?.trim()) return { apiKey: cred.key, source: "plaintext", discoveryApiKey: toDiscoveryApiKey(cred.key) }; return; } ... } ```

With the new env secret ref format, when a credential profile has:

  • `keyRef` set to a valid ref → the first `if` branch is entered correctly
  • BUT if the profile was somehow migrated/normalized such that `cred.key` itself became a ref object (e.g. `{ source: "env", id: "SOME_VAR" }`) rather than plain text, the fallback line `cred.key?.trim()` throws because objects have no `.trim()`.

It could also happen when:\n- The auth profile format changes between versions and old `key: { ... }` objects remain in the credential store, while previously `key` was always a string

  • The profile store or migration logic writes an object to `cred.key` instead of moving it to `cred.keyRef`

Expected behavior

The credential resolver should guard against non-string values in `cred.key` before calling `.trim()`, or ensure the migration from `key` → `keyRef` format completes so that old object-shaped keys never reach the fallback path.

Proposed fix

```js // current (crashes): if (cred.key?.trim()) return { ... }

// fix: add typeof guard if (typeof cred.key === "string" && cred.key.trim()) return { ... } ```

Or better yet, ensure the credential store migration properly converts any object-valued `key` to `keyRef` so the fallback only ever sees plain strings.

Environment

  • openclaw version: 2026.3.31
  • Node.js: v22.22.0
  • OS: Linux 6.17.0-1009-oracle (arm64)
  • Affected providers: All (OpenRouter, DeepSeek, Google, OpenAI Codex, etc.)

Reproduction

  1. Run openclaw 2026.3.28 with auth profiles that may contain non-plaintext key values
  2. Upgrade to openclaw 2026.3.31\n3. Trigger any model call (e.g. send a message)\n4. Observe `cred.key?.trim is not a function` error

Impact\nCritical — complete inability to resolve any model API key after upgrade. No agent can reply.

Logs

``` openclaw logs --follow\n\n[plugins] matrix: ... (normal)\nAgent failed before reply: cred.key?.trim is not a function ```


Labels: bug, auth, regression, credential-management

extent analysis

TL;DR

Add a typeof guard to check if cred.key is a string before calling trim() on it to prevent the error.

Guidance

  • Verify that the cred.key value is indeed an object instead of a string by adding a console.log statement before the problematic line to inspect its type and content.
  • Apply the proposed fix by adding a typeof check: if (typeof cred.key === "string" && cred.key.trim()) return { ... }.
  • Consider ensuring the credential store migration properly converts any object-valued key to keyRef to prevent this issue in the future.
  • Test the fix by running the reproduction steps and verifying that the error no longer occurs.

Example

// current (crashes):
if (cred.key?.trim()) return { ... }

// fix: add typeof guard
if (typeof cred.key === "string" && cred.key.trim()) return { ... }

Notes

This fix assumes that cred.key should always be a string in the fallback path. If cred.key can be an object in certain cases, additional handling may be required.

Recommendation

Apply the workaround by adding the typeof guard to prevent the error, as the root cause is related to the change in cred.key type and the migration logic.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

The credential resolver should guard against non-string values in `cred.key` before calling `.trim()`, or ensure the migration from `key` → `keyRef` format completes so that old object-shaped keys never reach the fallback path.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix Bug: `cred.key?.trim is not a function` crash after upgrading to 2026.3.31 — env ref auth profiles not fully supported in credential resolution [1 participants]