Skip to content

Amazon Bedrock unable to interpret the lambda response

0

Here's my response code added to the lambda,

The response is coming in json in Lambda output: Status: Succeeded Test Event Name: sopselectorjira and here's the lamda code that developed for sop selection for incident.

import boto3 import json import requests import logging import re from requests.auth import HTTPBasicAuth from atlassian import Confluence

logger = logging.getLogger() logger.setLevel(logging.INFO)

─────────────────────────────────────────

GET SECRETS

─────────────────────────────────────────

def get_secret(secret_name): client = boto3.client('secretsmanager', region_name='us-east-2') response = client.get_secret_value(SecretId=secret_name) raw = json.loads(response['SecretString']) return {k.strip(): v.strip() if isinstance(v, str) else v for k, v in raw.items()}

─────────────────────────────────────────

CLEAN HTML ✅ FIXED

─────────────────────────────────────────

def clean_html(html: str) -> str: text = re.sub(r"<[^>]+>", " ", html) text = re.sub(r"\s+", " ", text).strip() return text

─────────────────────────────────────────

FETCH SOPs

─────────────────────────────────────────

def get_sops_from_confluence(confluence_url, email, token, space="SRE"): confluence = Confluence( url=confluence_url, username=email, password=token, cloud=True )

pages = confluence.get_all_pages_from_space(
    space=space,
    limit=50,
    expand="body.storage"
)

sops = []
for p in pages:
    body = clean_html(p["body"]["storage"]["value"])
    sops.append({
        "title": p["title"],
        "url": f"{confluence_url}/spaces/{space}/pages/{p['id']}",
        "body": body[:1500]
    })

return sops

─────────────────────────────────────────

PROMPT BUILDER ✅ FIXED

─────────────────────────────────────────

def build_prompt(ticket_body: str, sops: list) -> str: sop_list = ""

for i, sop in enumerate(sops):
    sop_list += (
        f"\nSOP #{i+1}:\n"
        f"Title: {sop['title']}\n"
        f"URL: {sop['url']}\n"
        f"Summary: {sop['body'][:300]}\n"
    )

return f"""

You are a senior SRE engineer.

Select the most relevant SOP.

INCIDENT: {ticket_body}

AVAILABLE SOPs: {sop_list}

Return ONLY JSON: {{ "sop_title": "...", "sop_url": "...", "confidence": "high | medium | low", "reason": "short explanation" }} """

─────────────────────────────────────────

BEDROCK CALL

─────────────────────────────────────────

def select_sop_with_bedrock(ticket_body, sops):

bedrock = boto3.client('bedrock-runtime', region_name='us-east-2')

#model_id = "arn:aws:bedrock:us-east-2:008971655733:application-inference-profile/paz9kbmgbj6s"
model_id="amazon.nova-premier-v1:0"

prompt = build_prompt(ticket_body, sops)

response = bedrock.converse(
    modelId=model_id,
    messages=[{
        "role": "user",
        "content": [{"text": prompt}]
    }],
    inferenceConfig={
        "maxTokens": 512,
        "temperature": 0
    }
)

raw_text = response["output"]["message"]["content"][0]["text"]

clean = re.sub(r"^```json|```$", "", raw_text, flags=re.MULTILINE).strip()
match = re.search(r"\{.*\}", clean, re.DOTALL)

if not match:
    return fallback_sop(sops, "No JSON detected")

try:
    return json.loads(match.group())
except Exception:
    return fallback_sop(sops, "Parsing error")

─────────────────────────────────────────

FALLBACK

─────────────────────────────────────────

def fallback_sop(sops, reason): if not sops: return { "sop_title": "No SOP available", "sop_url": "N/A", "confidence": "low", "reason": reason }

return {
    "sop_title": sops[0]["title"],
    "sop_url": sops[0]["url"],
    "confidence": "low",
    "reason": reason
}

─────────────────────────────────────────

JIRA UPDATE

─────────────────────────────────────────

def post_sop_to_jira(issue_key, sop, jira_url, email, token):

url = f"{jira_url}/rest/api/3/issue/{issue_key}/comment"
auth = HTTPBasicAuth(email, token)

payload = {
    "body": {
        "type": "doc",
        "version": 1,
        "content": [
            {
                "type": "paragraph",
                "content": [
                    {"type": "text", "text": "SOP: "},
                    {
                        "type": "text",
                        "text": sop['sop_title'],
                        "marks": [
                            {
                                "type": "link",
                                "attrs": {"href": sop['sop_url']}
                            }
                        ]
                    }
                ]
            }
        ]
    }
}

requests.post(url, json=payload, auth=auth)

─────────────────────────────────────────

✅ FINAL RESPONSE (TEXT FORMAT — CRITICAL FIX)

─────────────────────────────────────────

def format_bedrock_response(event, sop): return { "messageVersion": "1.0", "response": { "actionGroup": event.get("actionGroup", ""), "function": event.get("function", ""), "functionResponse": { "responseBody": { "text/plain": json.dumps(sop) } } } }

─────────────────────────────────────────

✅ LAMBDA HANDLER

─────────────────────────────────────────

def lambda_handler(event, context):

try:
    logger.info(f"Incoming event: {json.dumps(event)}")

    creds = get_secret('jira-credentials')

    # ✅ Convert parameters list → dict
    body = {}
    if isinstance(event.get("parameters"), list):
        for p in event["parameters"]:
            body[p.get("name")] = p.get("value")
    elif isinstance(event.get("parameters"), dict):
        body = event["parameters"]
    else:
        body = event

    logger.info(f"Processed body: {json.dumps(body)}")

    # ✅ Convert string → issue object
    if isinstance(body.get("issue"), str):
        user_input = body.get("issue")
        body["issue"] = {
            "key": "INC-23",
            "fields": {
                "summary": user_input,
                "description": user_input
            }
        }

    issue = body.get("issue", {})
    key = issue.get("key", "INC-23")
    summary = issue.get("fields", {}).get("summary", "")

    if "latency" in summary.lower() or "issue" in summary.lower():
        sops = get_sops_from_confluence(
            creds["confluence_url"],
            creds["jira_email"],
            creds["confluence_token"]
        )

        sop = select_sop_with_bedrock(summary, sops)

        post_sop_to_jira(
            key,
            sop,
            creds["jira_url"],
            creds["jira_email"],
            creds["jira_api_token"]
        )
    else:
        sop = {
            "sop_title": "N/A",
            "sop_url": "N/A",
            "confidence": "low",
            "reason": "Not a valid incident"
        }

    return format_bedrock_response(event, sop)

except Exception as e:
    logger.error(str(e))
    return format_bedrock_response(event, {
        "sop_title": "Error",
        "sop_url": "N/A",
        "confidence": "low",
        "reason": str(e)
    })

The area below shows the last 4 KB of the execution log.

We are encountering the following error in Bedrock: "The server encountered an error processing the Lambda response. Check the Lambda response and retry the request."

Could you please advise if any changes are required in the Lambda response formatting (specifically in the format_bedrock_response function)?

Your assistance on this would be highly appreciated.

1 Answer
2

Based on the error you're encountering, the issue is likely with how your Lambda function is formatting the response for Amazon Bedrock. When using Bedrock with Lambda functions (particularly as action group executors for Agents), the response structure must follow a specific format.

The key issue in your format_bedrock_response function is the content type specification. Your current code uses:

"responseBody": {
"text/plain": json.dumps(sop)
}

However, for Bedrock to properly interpret the Lambda response, you should use TEXT as the content type key (not text/plain), and the structure should be:

"responseBody": {
"TEXT": {
"body": json.dumps(sop)
}
}

Here's the corrected format_bedrock_response function:

def format_bedrock_response(event, sop):
return {
"messageVersion": "1.0",
"response": {
"actionGroup": event.get("actionGroup", ""),
"function": event.get("function", ""),
"functionResponse": {
"responseBody": {
"TEXT": {
"body": json.dumps(sop)
}
}
}
}
}

Additionally, ensure that:

  1. The messageVersion is set to "1.0"
  2. The actionGroup and function fields match what's defined in your Bedrock Agent configuration
  3. The response body contains valid JSON that can be parsed by Bedrock

If you're still experiencing issues after this change, verify that:

  • Your Lambda function has the correct permissions to be invoked by Bedrock
  • The action group in your Bedrock Agent is properly configured to call this Lambda function
  • The function name in the event matches your Agent's action group configuration

The response structure is critical for Bedrock to properly process the Lambda output, and using the correct content type format should resolve the error you're seeing.

answered a month ago

EXPERT

reviewed a month ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.