openclaw - 💡(How to fix) Fix [Bug]: Bedrock embedding fails with ValidationException when model id has inference-profile prefix (global.cohere.embed-v4:0)

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…

Bedrock embedding adapter fails with ValidationException: Malformed request when configured with an inference-profile-prefixed model id (e.g. global.cohere.embed-v4:0), because resolveSpec() and inferFamily() do not strip the global. / us. / apac. / eu. / us-gov. prefix before catalog lookup, causing the family to silently fall back to titan-v1 and the wrong request body to be built.

Error Message

[memory] sync failed (session-start): ValidationException: Malformed request. Please check your parameter/values and try again. [memory] sync failed (search): ValidationException: Malformed request. Please check your parameter/values and try again.

Root Cause

Bedrock embedding adapter fails with ValidationException: Malformed request when configured with an inference-profile-prefixed model id (e.g. global.cohere.embed-v4:0), because resolveSpec() and inferFamily() do not strip the global. / us. / apac. / eu. / us-gov. prefix before catalog lookup, causing the family to silently fall back to titan-v1 and the wrong request body to be built.

Fix Action

Fix / Workaround

After applying a local patch that adds stripInferenceProfilePrefix(modelId) and uses the bare id for resolveSpec() and inferFamily() (while keeping the full id for InvokeModelCommand.modelId), every embedding call succeeds and the memory index builds normally (1400+ chunks × 1536 dims per agent).

Affected: any OpenClaw deployment using a Bedrock embedding model that requires inference-profile invocation. That includes cohere.embed-v4:0 in many regions (us-west-2, eu-, apac-) where on-demand direct invoke is not supported. The us./global./apac./eu./us-gov. prefix is standard AWS Bedrock practice for a growing list of models. Severity: Completely blocks the memory system when configured against affected models. Agents lose semantic recall; active-memory and dreaming promotion all cascade to failure. Frequency: Always, on every session that triggers a memory operation. Deterministic. Consequence: Users must either (a) switch to a model that supports on-demand invoke (losing Cohere v4 embedding quality), (b) downgrade memorySearch provider to Gemini / Voyage / OpenAI / Ollama (adds another provider account / API key / infra), or (c) patch the bundle locally and re-patch on every OpenClaw upgrade.

Code Example

{
     "agents": {
       "defaults": {
         "memorySearch": {
           "provider": "bedrock",
           "model": "global.cohere.embed-v4:0"
         }
       }
     },
     "env": {
       "AWS_BEARER_TOKEN_BEDROCK": "<redacted>",
       "AWS_REGION": "us-west-2"
     }
   }

---

[memory] sync failed (session-start): ValidationException: Malformed request. Please check your parameter/values and try again.
   [memory] sync failed (search): ValidationException: Malformed request. Please check your parameter/values and try again.

---

function inferFamily(modelId) {
    const id = normalizeLowercaseStringOrEmpty(modelId);
    if (id.startsWith("amazon.titan-embed-text-v2")) return "titan-v2";
    if (id.startsWith("amazon.titan-embed")) return "titan-v1";
    if (id.startsWith("amazon.nova")) return "nova";
    if (id.startsWith("cohere.embed-v4")) return "cohere-v4";
    if (id.startsWith("cohere.embed")) return "cohere-v3";
    if (id.startsWith("twelvelabs.")) return "twelvelabs";
    return "titan-v1";  // ← fallback when nothing matches
}

---

{
  "models": {
    "providers": {
      "amazon-bedrock": {
        "baseUrl": "https://bedrock-runtime.us-west-2.amazonaws.com",
        "auth": "aws-sdk",
        "api": "bedrock-converse-stream"
      }
    }
  }
}

---

[memory] sync failed (session-start): ValidationException: Malformed request. Please check your parameter/values and try again.
[memory] sync failed (search): ValidationException: Malformed request. Please check your parameter/values and try again.
[agent/embedded] embedded run failover decision: runId=active-memory-... stage=assistant decision=surface_error reason=none from=amazon-bedrock/global.anthropic.claude-sonnet-4-6 profile=-

---

aws bedrock-runtime invoke-model --region us-west-2 \
  --model-id global.cohere.embed-v4:0 \
  --body "$(echo '{"texts":["hello"],"input_type":"search_document","truncate":"END"}' | base64 -w0)" \
  --cli-binary-format base64 /tmp/out.json
# Returns {"embeddings":{"float":[[...1536 floats...]]}, "response_type":"embeddings_by_type", ...}

---

function stripInferenceProfilePrefix(modelId) {
    return modelId.replace(/^(us-gov|us|global|apac|eu)\./, "");
}

function resolveSpec(modelId) {
    const bare = stripInferenceProfilePrefix(modelId);
    if (MODELS[bare]) return MODELS[bare];
    const parts = bare.split(":");
    for (let i = parts.length - 1; i >= 1; i--) {
        const spec = MODELS[parts.slice(0, i).join(":")];
        if (spec) return spec;
    }
}

function inferFamily(modelId) {
    const id = normalizeLowercaseStringOrEmpty(stripInferenceProfilePrefix(modelId));
    // ...rest unchanged...
}
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

Bedrock embedding adapter fails with ValidationException: Malformed request when configured with an inference-profile-prefixed model id (e.g. global.cohere.embed-v4:0), because resolveSpec() and inferFamily() do not strip the global. / us. / apac. / eu. / us-gov. prefix before catalog lookup, causing the family to silently fall back to titan-v1 and the wrong request body to be built.

Steps to reproduce

  1. Configure memorySearch against Bedrock with an inference-profile-prefixed Cohere model id:
    {
      "agents": {
        "defaults": {
          "memorySearch": {
            "provider": "bedrock",
            "model": "global.cohere.embed-v4:0"
          }
        }
      },
      "env": {
        "AWS_BEARER_TOKEN_BEDROCK": "<redacted>",
        "AWS_REGION": "us-west-2"
      }
    }
  2. Restart gateway. Cause any agent to trigger memory_search (e.g. user asks a question that requires recall).
  3. Observe gateway log entries:
    [memory] sync failed (session-start): ValidationException: Malformed request. Please check your parameter/values and try again.
    [memory] sync failed (search): ValidationException: Malformed request. Please check your parameter/values and try again.

For context, cohere.embed-v4:0 in us-west-2 does not support on-demand invoke directly — the AWS CLI aws bedrock-runtime invoke-model --model-id cohere.embed-v4:0 ... returns Invocation of model ID cohere.embed-v4:0 with on-demand throughput isn't supported. Retry your request with the ID or ARN of an inference profile that contains this model. So using the global.cohere.embed-v4:0 inference profile is the required invocation form, not a preference.

Expected behavior

The Bedrock embedding adapter should recognize inference-profile-prefixed model ids and route them to the correct family (cohere-v4 in this case), so the request body uses the Cohere v4 schema {texts, input_type, truncate} instead of the Titan v1 fallback schema {inputText}. The InvokeModelCommand.modelId should continue using the original prefixed id so Bedrock resolves the inference profile correctly.

Direct invocation of the same inference profile with the Cohere v4 body shape succeeds against the same Bedrock account/credentials, confirming the model itself is reachable — only the body that the OpenClaw adapter builds is wrong.

Actual behavior

In dist/embedding-provider-*.js (2026.5.6 filename: embedding-provider-BjKhpOVm.js), inferFamily() uses startsWith() against the unstripped model id:

function inferFamily(modelId) {
    const id = normalizeLowercaseStringOrEmpty(modelId);
    if (id.startsWith("amazon.titan-embed-text-v2")) return "titan-v2";
    if (id.startsWith("amazon.titan-embed")) return "titan-v1";
    if (id.startsWith("amazon.nova")) return "nova";
    if (id.startsWith("cohere.embed-v4")) return "cohere-v4";
    if (id.startsWith("cohere.embed")) return "cohere-v3";
    if (id.startsWith("twelvelabs.")) return "twelvelabs";
    return "titan-v1";  // ← fallback when nothing matches
}

"global.cohere.embed-v4:0".startsWith("cohere.embed-v4") evaluates to false, so family silently falls back to titan-v1. The subsequent buildBody("titan-v1", text, dims) produces JSON.stringify({inputText: text}), which Bedrock then routes to the global.cohere.embed-v4:0 inference profile. Cohere's v4 endpoint rejects the Titan-v1 body shape with Malformed request.

resolveSpec() has the same blind spot — it looks up the MODELS catalog with the full model id and falls through to undefined, losing dimension/context-window metadata.

OpenClaw version

2026.5.6

Operating system

Ubuntu 24.04 LTS, x86_64

Install method

npm install -g openclaw, gateway as user-mode systemd service

Model

Embedding model: cohere.embed-v4:0 via global.cohere.embed-v4:0 inference profile (also reproduces with us.cohere.embed-v4:0)

Provider / routing chain

memory-core -> openclaw embedding adapter (dist/embedding-provider-*.js) -> @aws-sdk/client-bedrock-runtime InvokeModelCommand -> bedrock-runtime.us-west-2.amazonaws.com -> global.cohere.embed-v4:0 inference profile -> cohere.embed-v4:0

Additional provider/model setup details

AWS Bedrock config block in openclaw.json:

{
  "models": {
    "providers": {
      "amazon-bedrock": {
        "baseUrl": "https://bedrock-runtime.us-west-2.amazonaws.com",
        "auth": "aws-sdk",
        "api": "bedrock-converse-stream"
      }
    }
  }
}

Auth via AWS_BEARER_TOKEN_BEDROCK env var (Bedrock API-key style, not IAM SigV4). Same issue would reproduce with IAM-credential auth — the failure is in request-body construction, not in auth.

Logs, screenshots, and evidence

Gateway log excerpt on failure (redacted paths):

[memory] sync failed (session-start): ValidationException: Malformed request. Please check your parameter/values and try again.
[memory] sync failed (search): ValidationException: Malformed request. Please check your parameter/values and try again.
[agent/embedded] embedded run failover decision: runId=active-memory-... stage=assistant decision=surface_error reason=none from=amazon-bedrock/global.anthropic.claude-sonnet-4-6 profile=-

Direct AWS CLI invocation with the Cohere v4 body shape against the same inference profile — succeeds, confirming credentials + model + profile are fine:

aws bedrock-runtime invoke-model --region us-west-2 \
  --model-id global.cohere.embed-v4:0 \
  --body "$(echo '{"texts":["hello"],"input_type":"search_document","truncate":"END"}' | base64 -w0)" \
  --cli-binary-format base64 /tmp/out.json
# Returns {"embeddings":{"float":[[...1536 floats...]]}, "response_type":"embeddings_by_type", ...}

After applying a local patch that adds stripInferenceProfilePrefix(modelId) and uses the bare id for resolveSpec() and inferFamily() (while keeping the full id for InvokeModelCommand.modelId), every embedding call succeeds and the memory index builds normally (1400+ chunks × 1536 dims per agent).

Impact and severity

Affected: any OpenClaw deployment using a Bedrock embedding model that requires inference-profile invocation. That includes cohere.embed-v4:0 in many regions (us-west-2, eu-, apac-) where on-demand direct invoke is not supported. The us./global./apac./eu./us-gov. prefix is standard AWS Bedrock practice for a growing list of models. Severity: Completely blocks the memory system when configured against affected models. Agents lose semantic recall; active-memory and dreaming promotion all cascade to failure. Frequency: Always, on every session that triggers a memory operation. Deterministic. Consequence: Users must either (a) switch to a model that supports on-demand invoke (losing Cohere v4 embedding quality), (b) downgrade memorySearch provider to Gemini / Voyage / OpenAI / Ollama (adds another provider account / API key / infra), or (c) patch the bundle locally and re-patch on every OpenClaw upgrade.

Additional information

Suggested fix — add a small helper and use it in the two catalog lookup paths, keeping InvokeModelCommand.modelId on the full prefixed id:

function stripInferenceProfilePrefix(modelId) {
    return modelId.replace(/^(us-gov|us|global|apac|eu)\./, "");
}

function resolveSpec(modelId) {
    const bare = stripInferenceProfilePrefix(modelId);
    if (MODELS[bare]) return MODELS[bare];
    const parts = bare.split(":");
    for (let i = parts.length - 1; i >= 1; i--) {
        const spec = MODELS[parts.slice(0, i).join(":")];
        if (spec) return spec;
    }
}

function inferFamily(modelId) {
    const id = normalizeLowercaseStringOrEmpty(stripInferenceProfilePrefix(modelId));
    // ...rest unchanged...
}

Only resolveSpec / inferFamily care about the "bare" id. InvokeModelCommand.modelId must continue to use the full prefixed id so Bedrock routes to the correct inference profile.

Happy to open a PR for this change. Scope is small and localized to the embedding provider source.

Same pattern likely applies to other Bedrock adapter code paths that do model-id matching (LLM provider routing, streaming, thinking-mode gating, etc.) — worth a grep for similar startsWith("<provider>.<family>") patterns against inference-profile-capable model ids.

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 Bedrock embedding adapter should recognize inference-profile-prefixed model ids and route them to the correct family (cohere-v4 in this case), so the request body uses the Cohere v4 schema {texts, input_type, truncate} instead of the Titan v1 fallback schema {inputText}. The InvokeModelCommand.modelId should continue using the original prefixed id so Bedrock resolves the inference profile correctly.

Direct invocation of the same inference profile with the Cohere v4 body shape succeeds against the same Bedrock account/credentials, confirming the model itself is reachable — only the body that the OpenClaw adapter builds is wrong.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING