{"record":{"id":"a329a792f6240020","repo":"BerriAI/litellm","slug":"guardrailconfig-raw-guardrail-config-is-missing","errorCode":null,"errorMessage":"guardrailConfig={raw_guardrail_config} is missing 'guardrailIdentifier'. Expected format: {_GUARDRAIL_CONFIG_EXPECTED_FORMAT}","messagePattern":"guardrailConfig=(.+?) is missing 'guardrailIdentifier'\\. Expected format: (.+?)","errorType":"http","errorClass":"BedrockError","httpStatus":400,"severity":"error","filePath":"litellm/llms/bedrock/chat/invoke_transformations/base_invoke_transformation.py","lineNumber":58,"sourceCode":"from litellm.llms.bedrock.base_aws_llm import BaseAWSLLM\n\n_GUARDRAIL_CONFIG_VALIDATOR: Final[\"TypeAdapter[GuardrailConfigBlock]\"] = TypeAdapter(GuardrailConfigBlock)\n\n_GUARDRAIL_CONFIG_EXPECTED_FORMAT: Final = (\n    \"{'guardrailIdentifier': str, 'guardrailVersion': str, 'trace': 'enabled'|'disabled'|'enabled_full'}\"\n)\n\n\ndef _bedrock_invoke_guardrail_headers(raw_guardrail_config: object) -> \"dict[str, str]\":\n    try:\n        guardrail_config: Final = _GUARDRAIL_CONFIG_VALIDATOR.validate_python(raw_guardrail_config)\n    except ValidationError as e:\n        raise BedrockError(\n            status_code=400,\n            message=f\"Invalid guardrailConfig={raw_guardrail_config}. Expected format: {_GUARDRAIL_CONFIG_EXPECTED_FORMAT}. Error: {e}\",\n        )\n    if \"guardrailIdentifier\" not in guardrail_config:\n        raise BedrockError(\n            status_code=400,\n            message=f\"guardrailConfig={raw_guardrail_config} is missing 'guardrailIdentifier'. Expected format: {_GUARDRAIL_CONFIG_EXPECTED_FORMAT}\",\n        )\n    trace: Final = guardrail_config.get(\"trace\")\n    candidate_headers: Final = {\n        \"X-Amzn-Bedrock-GuardrailIdentifier\": guardrail_config.get(\"guardrailIdentifier\"),\n        \"X-Amzn-Bedrock-GuardrailVersion\": guardrail_config.get(\"guardrailVersion\"),\n        \"X-Amzn-Bedrock-Trace\": trace.upper() if trace is not None else None,\n    }\n    return {name: value for name, value in candidate_headers.items() if value is not None}\n\n\nclass AmazonInvokeConfig(BaseConfig, BaseAWSLLM):\n    def __init__(self, **kwargs):\n        BaseConfig.__init__(self, **kwargs)\n        BaseAWSLLM.__init__(self, **kwargs)\n\n    def get_supported_openai_params(self, model: str) -> list[str]:","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/bedrock/chat/invoke_transformations/base_invoke_transformation.py#L40-L76","documentation":"Raised by _bedrock_invoke_guardrail_headers when the validated guardrailConfig dict is missing the required 'guardrailIdentifier' key. This is a separate check after pydantic validation (which permits the key to be absent), producing a BedrockError 400 that echoes the raw config and the expected format string.","triggerScenarios":"Passing a guardrailConfig like {'guardrailVersion': '1'} or {'trace': 'enabled'} without a guardrailIdentifier to a bedrock/ invoke call that activates guardrail header generation.","commonSituations":"Developers enabling trace-only usage and assuming the identifier is optional, config built dynamically where the identifier key is dropped when its value is None, or copy-paste from partial examples.","solutions":["Add 'guardrailIdentifier' with your guardrail ID or full ARN (e.g. 'gr-abcdef123' or 'arn:aws:bedrock:us-east-1:...:guardrail/gr-...').","If building config dynamically, skip guardrailConfig entirely when no identifier is configured instead of sending a partial dict.","Do not send guardrail headers at all if you do not want guardrails applied."],"exampleFix":"# before\nextra_body={\"guardrailConfig\": {\"guardrailVersion\": \"1\", \"trace\": \"enabled\"}}\n\n# after\nextra_body={\"guardrailConfig\": {\n    \"guardrailIdentifier\": \"gr-abcdef123\",\n    \"guardrailVersion\": \"1\",\n    \"trace\": \"enabled\",\n}}","handlingStrategy":"validation","validationCode":"if use_guardrails:\n    if not guardrail_identifier:\n        raise ValueError(\"guardrailIdentifier is required when guardrails are enabled\")\n    extra_body = {\"guardrailConfig\": {\n        \"guardrailIdentifier\": guardrail_identifier,\n        \"guardrailVersion\": guardrail_version or \"1\",\n        \"trace\": trace or \"enabled\",\n    }}\nelse:\n    extra_body = {}  # send nothing rather than a partial config","typeGuard":"def has_guardrail_identifier(cfg: object) -> bool:\n    return isinstance(cfg, dict) and isinstance(cfg.get(\"guardrailIdentifier\"), str) and len(cfg[\"guardrailIdentifier\"]) > 0","tryCatchPattern":"from litellm.exceptions import BedrockError\ntry:\n    litellm.completion(model=\"bedrock/<model>\", messages=msgs, extra_body={\"guardrailConfig\": cfg})\nexcept BedrockError as e:\n    if e.status_code == 400 and \"missing 'guardrailIdentifier'\" in str(e):\n        cfg.setdefault(\"guardrailIdentifier\", DEFAULT_GUARDRAIL_ID)\n        retry()\n    raise","preventionTips":["Build guardrail config only when a guardrail ID is present; omit it otherwise.","Fail fast in config loading if guardrails are requested without an identifier."],"tags":["aws","bedrock","guardrails","validation","configuration"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}