Skip to content

Bedrock Runtime: inline image history still overflows after successful compaction #46247

Open

Description

@cncoder

What version of Codex CLI is running?

codex-cli 0.154.0 (latest stable release checked on 2026-09-18).

What subscription do you have?

Amazon Bedrock API, pay-as-you-go. This is the built-in amazon-bedrock-runtime provider, not a ChatGPT subscription.

Which model were you using?

global.openai.gpt-6-astra. Similar failures were observed in a separate global.openai.gpt-5.6-sol session. The controlled reproduction below keeps the model, AWS identity, and endpoint Region unchanged.

What platform is your computer?

Linux 6.17.0-1020-aws, x86_64; Ubuntu 24.04.

What terminal emulator and version are you using?

CLI through tmux 3.4. Also reproduced through the installed Codex app-server's stdio API, so this is not limited to terminal rendering.

What issue are you seeing?

Image-heavy conversations can fail with the following Bedrock Runtime response while still well below Codex's configured token-based compaction threshold:

{
  "error": {
    "message": "Input is too long.",
    "type": "invalid_request_error",
    "param": null,
    "code": "validation_error"
  }
}

Attempting compaction can fail with the same error:

Error running remote compact task: {"error":{"message":"Input is too long.","type":"invalid_request_error","param":null,"code":"validation_error"}}

Reducing the token threshold alone did not resolve this. With model_auto_compact_token_limit = 50000, a fresh thread accepted two PNGs per turn. Turns 6 through 10 each completed a remote compaction, but submitting images 21–22 failed with the same error. The last successful request used 74,965 input tokens. Completed compacted records continued retaining the historical inline images.

Controlled observations

A/B measurements were collected on 2026-09-17.

A separate direct Responses API test used the same 23 images, model, Region, and image dimensions. The request only asked for a short acknowledgement, with store=false. The image set is private and is not attached.

Encoding Images JSON request bytes Result
Original PNG 23 36,124,273 HTTP 400, Input is too long.
Recompressed PNG, identical decoded pixels 23 33,508,621 HTTP 400, same error
Lossless WebP, identical decoded pixels and dimensions 23 20,285,972 HTTP 200, 53,008 input tokens
JPEG, same dimensions, lossy control 23 8,444,564 HTTP 200, 53,008 input tokens

The lossless conversion was checked by comparing decoded RGBA pixel buffers. These observations point to an encoded-payload constraint that token accounting alone does not protect against. They do not establish an exact or universal Bedrock request-size limit.

In affected full conversations, the latest active history contained approximately 20–23 inline images and 30–36 MB of encoded image content. One affected conversation's last successful full-history request used only 153,997 input tokens.

What steps can reproduce the bug?

  1. Use Codex 0.154.0 with the built-in amazon-bedrock-runtime provider and a supported multimodal model.
  2. Keep the model, credentials, and endpoint Region unchanged throughout the test.
  3. Start a fresh thread and submit two reasonably large PNG screenshots per turn, asking for a short acknowledgement without tool calls. Alternatively, accumulate screenshots through image-producing tools.
  4. Continue until the active inline image payload grows into the tens of megabytes.
  5. Observe a Bedrock validation_error even though token usage has not reached the configured context limit.
  6. Try /compact; it can fail with the same oversized input.
  7. Repeat in a fresh thread with the auto-compaction threshold lowered to 50,000 tokens. In the observed run, remote compaction completed five times but retained enough inline images for the 22-image request to fail anyway.

For the controlled API comparison, use POST https://bedrock-runtime.us-east-1.amazonaws.com/openai/v1/responses, a user content array of input_image data URLs, the same detail values, and the same short text instruction. Compare original PNG data URLs against losslessly re-encoded copies of those images.

What is the expected behavior?

  • Track encoded image/request bytes separately from model token usage.
  • Trigger compaction before the provider's encoded-payload constraint is exhausted.
  • Ensure that the retained post-compaction image payload fits a bounded budget; a successful compaction should make continued progress possible.
  • Provide a recovery path for already oversized histories without requiring users to edit private rollout files or encrypted reasoning content.
  • Keep image content, text, and associated history metadata consistent during any transformation.

Technical observations

On the rust-v0.154.0 source:

  • Image token estimation intentionally discounts raw Base64 bytes. This is appropriate for vision-token accounting but does not enforce a separate transport budget.
  • core/src/compact_remote_v2.rs uses a RETAINED_MESSAGE_TOKEN_BUDGET of 64,000. An image set can fit that token budget while its encoded representation remains too large for the provider.
  • Bedrock returns validation_error for the observed failure, rather than context_length_exceeded.

Configuration used in the lower-threshold reproduction:

model_provider = "amazon-bedrock-runtime"
model = "global.openai.gpt-6-astra"
model_context_window = 872000
model_auto_compact_token_limit = 50000
model_auto_compact_token_limit_scope = "total"
model_reasoning_effort = "xhigh"

[model_providers.amazon-bedrock-runtime.aws]
region = "us-east-1"

Codex reported an effective model context window of 828,400 tokens. No custom provider proxy was used.

Related reports

This report adds a current stable Bedrock Runtime reproduction, the validation_error response shape, a same-pixel encoding comparison, and a negative control showing that earlier token-based compaction can still retain an oversized image payload.

Privacy and validation limits

Only sanitized structural measurements are included. No screenshots, private prompts, account identifiers, credentials, or raw rollouts are attached. The exact provider byte limit and behavior on other providers have not been established.

A local experimental implementation allowed the 23-image batch followed by another 32 images to continue, with automatic compaction, manual compaction, and a restart/recall check. That implementation is still under validation and is not being presented as a completed upstream fix.

Activity

  1. added
    bugSomething isn't working
    CLIIssues related to the Codex CLI
    contextIssues related to context management (including compaction)
    aws-bedrockIssues related to AWS Bedrock provider
    on Sep 17, 2026
  2. github-actions commented on Sep 17, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

  3. cncoder commented on Sep 17, 2026

    @cncoder
    Author

    Additional same-format reproduction, without private screenshots:

    • Both requests contain the same 32 PNG images, each 64×64 with identical pixels and dimensions.
    • Only the amount of inert EXIF padding changes.
    • At 34,143,253 JSON request bytes, Bedrock returns HTTP 400 with Input is too long. / validation_error.
    • At 25,609,877 bytes, it returns HTTP 200 and reports 324 input tokens.

    This isolates the encoded-payload constraint from image format, image count, and vision-token pressure. It does not establish an exact universal service quota.

    Synthetic image generator:

    import base64
    import io
    from PIL import Image
    
    def png_with_metadata(padding_bytes):
        exif = bytes([
            0x49, 0x49, 0x2a, 0, 8, 0, 0, 0, 1, 0, 0x12, 1, 3, 0,
            1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
        ]).ljust(padding_bytes, b"\0")
        output = io.BytesIO()
        Image.new("RGB", (64, 64), (100, 120, 140)).save(
            output, format="PNG", exif=exif
        )
        return {
            "type": "input_image",
            "detail": "high",
            "image_url": "data:image/png;base64,"
            + base64.b64encode(output.getvalue()).decode(),
        }

    Using the same authenticated Bedrock Runtime Responses request and model, compare a user content array containing 32 copies of png_with_metadata(800_000) with 32 copies of png_with_metadata(600_000), plus a short acknowledgement instruction. The measurements above used store=false, max_output_tokens=256, and reasoning={"effort": "low"}.

    A tested implementation is available for reference in cncoder/codex#1, commit 9aa90db. This is a fork-local review PR, not an upstream PR: GitHub rejected CreatePullRequest on openai/codex for my account.

    The implementation preserves newly submitted images, applies a byte budget at existing compaction boundaries, and bounds retained inline images without manufacturing or misaligning message metadata. All 8 new unit tests and both integration tests pass. A real Bedrock run of 23 images in one batch followed by 32 additional images passed, including six automatic compactions, manual compaction, and restart/recall.

    The broader selected suites report 86 passes and one sandbox-read-deny failure; that failure reproduces unchanged on the upstream baseline on this host. Full workspace and remote-platform validation are not claimed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIaws-bedrockIssues related to AWS Bedrock providerbugSomething isn't workingcontextIssues related to context management (including compaction)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions