April 14, 2026 โ€ข Version: 2026.4.11

Hardcoded 5MB Media Store Limit Blocks Generated Media Before Channel Limits Apply

OpenClaw enforces a hardcoded 5MB staging limit in the runtime bundle that silently overrides channel and agent-level media configurations, causing 'Media exceeds 5MB limit' errors for valid large media workflows.

๐Ÿ” Symptoms

The hardcoded media staging limit manifests through several distinct error patterns:

Primary Error Manifestation

When attempting to stage or return media files exceeding 5MB, the following error surfaces:

Error: Media exceeds 5MB limit
    at MediaStore.validateSize (dist/store-CA7OW_2w.js:XX:XX)
    at MediaStore.stage (dist/store-CA7OW_2w.js:XX:XX)
    at MediaPipeline.processOutput (dist/store-CA7OW_2w.js:XX:XX)
    at async CodexAgent.handleToolResult (dist/store-CA7OW_2w.js:XX:XX)

Error Flow During Media Processing

The error occurs during the staging validation phase of the media pipeline, before any downstream channel-specific limit resolution:

  1. Ingest Phase โ€” Media generated or received by the agent
  2. Staging Validation โ€” Hardcoded 5MB check in dist/store-CA7OW_2w.js โ† Failure point
  3. Channel Resolution โ€” Channel/agent media limits (never reached)
  4. Delivery โ€” Output to configured channel

Conditions That Trigger the Issue

  • Video generation workflows producing files > 5MB
  • Multi-image compositions or GIFs with frame data exceeding the threshold
  • Audio files with extended duration and high sample rates
  • Any media tool output staged through openclaw.media.stage()

Silent Override Behavior

The hardcoded limit silently overrides valid channel configurations. Users observing this behavior may notice:

# Channel config specifies 25MB limit
openclaw config get channels.slack.media.maxBytes
# Output: 26214400 (25MB)

# But generated media still fails at 5MB threshold
openclaw run --tool video-generate --prompt "Generate a 30-second clip"
# Error: Media exceeds 5MB limit

This creates a misleading experience where configured limits appear ineffective.

๐Ÿง  Root Cause

Architectural Issue: Premature Validation Gate

The root cause is a validation ordering problem in OpenClaw’s media pipeline architecture. The bundled runtime file dist/store-CA7OW_2w.js contains:

// From dist/store-CA7OW_2w.js
const MEDIA_MAX_BYTES = 5 * 1024 * 1024; // 5,242,880 bytes

class MediaStore {
  validateSize(bufferOrPath) {
    const size = this.getSize(bufferOrPath);
    if (size > MEDIA_MAX_BYTES) {
      throw new MediaLimitError(
        `Media exceeds ${MEDIA_MAX_BYTES} limit`
      );
    }
    // ... downstream processing
  }
}

Why This Causes the Problem

  1. Hardcoded Constant Outside Config Scope โ€” The MEDIA_MAX_BYTES value is compiled into the runtime bundle at build time and cannot be overridden via configuration files, environment variables, or runtime settings.
  2. Pipeline Position โ€” The validation occurs in the MediaStore.validateSize() method, which is invoked during the staging phase before any channel-specific limit resolution occurs.
  3. Absence of Config Inheritance โ€” The staging layer does not consult channel.media.maxBytes, agent.mediaLimits, or any other configuration hierarchy when enforcing this check.
  4. Silent Failure Path โ€” When the 5MB threshold is exceeded, the error is thrown without referencing any configurable limits or providing guidance about overriding the staging cap.

Intended vs. Actual Limit Hierarchy

OpenClaw’s design appears to intend a limit hierarchy where effective limits are resolved from multiple sources:

// Intended resolution order (never reached):
effectiveLimit = min(
  channel.media.maxBytes,    // e.g., 25MB for Slack
  agent.mediaLimits.maxBytes, // e.g., 10MB for specific agent
  globalDefaults.maxBytes    // e.g., 50MB global ceiling
)

However, the actual execution path short-circuits to the hardcoded 5MB value before any of these resolution paths execute.

Why This Exists

The 5MB hardcap likely originated as a safety measure to:

  • Prevent unbounded memory consumption during staging
  • Enforce a reasonable ceiling for "quick" media operations
  • Ensure predictable memory bounds in the staging layer

However, it was implemented as an opaque constant rather than a documented, configurable parameter with clear semantics.

๐Ÿ› ๏ธ Step-by-Step Fix

Solution 1: Derive Staging Limit from Effective Media Limits (Recommended)

Modify the MediaStore class to resolve the staging limit from the effective configuration hierarchy:

// Before (dist/store-CA7OW_2w.js)
const MEDIA_MAX_BYTES = 5 * 1024 * 1024;

class MediaStore {
  validateSize(bufferOrPath) {
    const size = this.getSize(bufferOrPath);
    if (size > MEDIA_MAX_BYTES) { /* error */ }
  }
}
// After (dist/store-CA7OW_2w.js)
const DEFAULT_STAGING_MAX_BYTES = 50 * 1024 * 1024; // 50MB default

class MediaStore {
  constructor(options = {}) {
    super(options);
    this._effectiveLimit = null;
  }

  getEffectiveLimit(context) {
    if (this._effectiveLimit !== null) {
      return this._effectiveLimit;
    }

    // Resolve from configuration hierarchy
    const configuredLimits = [
      context?.channel?.media?.maxBytes,
      context?.agent?.mediaLimits?.maxBytes,
      context?.config?.media?.stagingMaxBytes
    ].filter(limit => Number.isInteger(limit) && limit > 0);

    this._effectiveLimit = configuredLimits.length > 0
      ? Math.min(...configuredLimits)
      : DEFAULT_STAGING_MAX_BYTES;

    return this._effectiveLimit;
  }

  validateSize(bufferOrPath, context = {}) {
    const size = this.getSize(bufferOrPath);
    const effectiveLimit = this.getEffectiveLimit(context);

    if (size > effectiveLimit) {
      throw new MediaLimitError(
        `Media size (${size} bytes) exceeds effective limit of ${effectiveLimit} bytes ` +
        `(resolved from: ${JSON.stringify(context.channel?.media?.maxBytes ? 'channel' : 'default'})`
      );
    }
  }
}

Solution 2: Add Staging Limit Configuration (Workaround)

Until the above fix is available in a release, add the staging limit to the configuration system:

Step 1: Update configuration schema

# Add to openclaw.config.schema.json or equivalent
{
  "media": {
    "stagingMaxBytes": {
      "type": "integer",
      "default": 52428800,
      "description": "Maximum media size (in bytes) for staging/store operations",
      "env": "OPENCLAW_MEDIA_STAGING_MAX_BYTES"
    }
  }
}

Step 2: Modify MediaStore initialization

class MediaStore {
  constructor(options = {}) {
    const config = options.config || globalOpenClawConfig;
    this._stagingLimit = config.media?.stagingMaxBytes || DEFAULT_STAGING_MAX_BYTES;
  }
}

Step 3: Set via configuration

# In openclaw.config.yaml or openclaw.config.js
media:
  stagingMaxBytes: 26214400  # 25MB

# Or via environment variable
export OPENCLAW_MEDIA_STAGING_MAX_BYTES=26214400

Solution 3: Temporary Runtime Override (Immediate Workaround)

If you cannot modify the bundle directly, apply a monkey-patch before media operations:

// patch-media-limit.js
const originalRequire = module.constructor.prototype.require;

module.constructor.prototype.require = function(id) {
  const module = originalRequire.apply(this, arguments);

  if (id === './store' || id.includes('store-CA7OW')) {
    if (module.MediaStore) {
      const OriginalMediaStore = module.MediaStore;
      module.MediaStore = class PatchedMediaStore extends OriginalMediaStore {
        validateSize(...args) {
          // Override staging limit for this session
          const originalLimit = this.constructor.MEDIA_MAX_BYTES;
          try {
            this.constructor.MEDIA_MAX_BYTES = process.env.OPENCLAW_STAGING_MAX_BYTES || 52428800;
            return super.validateSize(...args);
          } finally {
            this.constructor.MEDIA_MAX_BYTES = originalLimit;
          }
        }
      };
    }
  }
  return module;
};

// Load before OpenClaw initialization
require('./patch-media-limit');
const { OpenClaw } = require('openclaw');

๐Ÿงช Verification

After applying the fix, verify the resolution through the following verification steps:

Prerequisites

# Ensure OpenClaw version includes the fix or workaround
openclaw --version
# Expected: 2026.4.12+ (or patched 2026.4.11)

# Verify configuration is set correctly
openclaw config get media.stagingMaxBytes
# Expected: > 5242880 (if explicitly set)

openclaw config get channels[0].media.maxBytes
# Expected: Your configured channel limit (e.g., 26214400 for 25MB)

Verification Test: Stage Media Exceeding Original 5MB Limit

# Create a test file exceeding 5MB (6MB)
dd if=/dev/urandom of=/tmp/test-media-6mb.bin bs=1M count=6

# Attempt to stage through OpenClaw media pipeline
node -e "
const { MediaStore } = require('openclaw/dist/store-CA7OW_2w');
const store = new MediaStore();
const fs = require('fs');

try {
  const buffer = fs.readFileSync('/tmp/test-media-6mb.bin');
  store.validateSize(buffer);
  console.log('SUCCESS: Media staged without error');
  console.log('Size validated:', buffer.length, 'bytes');
} catch (err) {
  console.error('FAILED:', err.message);
  process.exit(1);
}
"

# Expected output after fix:
# SUCCESS: Media staged without error
# Size validated: 6291456 bytes

Verification Test: Video Generation Workflow

# Run a video generation that produces > 5MB output
openclaw run \
  --tool video-generate \
  --prompt "Generate a 45-second animated landscape" \
  --output ./output/video.mp4

# Expected after fix:
# - Command completes without "Media exceeds 5MB limit" error
# - Output file exists and has expected size
ls -lh ./output/video.mp4
# Expected: file size > 5MB if generated successfully

Verification Test: Limit Hierarchy Resolution

# Test that effective limit respects the minimum of all configured limits
node -e "
const { MediaStore } = require('openclaw/dist/store-CA7OW_2w');
const store = new MediaStore({
  config: {
    media: { stagingMaxBytes: 10485760 }  // 10MB
  },
  channel: {
    media: { maxBytes: 5242880 }  // 5MB
  },
  agent: {
    mediaLimits: { maxBytes: 15728640 }  // 15MB
  }
});

const context = store.getEffectiveLimit({
  config: store._config,
  channel: store._config.channel,
  agent: store._config.agent
});

console.log('Effective limit:', context, 'bytes');
console.log('Expected: 5242880 (minimum of channel: 5MB)');
console.log('Result:', context === 5242880 ? 'PASS' : 'FAIL');
"

Verification Test: Error Message Clarity

# Test that error messages now indicate the effective limit source
node -e "
const { MediaStore, MediaLimitError } = require('openclaw/dist/store-CA7OW_2w');
const store = new MediaStore({ config: { media: { stagingMaxBytes: 1000000 } } });
const buffer = Buffer.alloc(2000000); // 2MB

try {
  store.validateSize(buffer);
} catch (err) {
  console.log('Error message:', err.message);
  // Expected: includes both size and effective limit
  // Should NOT just say 'Media exceeds 5MB limit'
}
"

# Expected: Error includes resolved effective limit, not hardcoded 5MB

โš ๏ธ Common Pitfalls

Environment-Specific Traps

  • Docker/Container Deployments โ€” The bundled runtime in dist/store-CA7OW_2w.js is embedded in the container image. Modifying node_modules inside a running container does not persist across restarts. Always rebuild images or mount configuration overrides.
    # Incorrect - changes lost after container restart
    docker exec openclaw-container sed -i 's/5 \* 1024 \* 1024/50 * 1024 * 1024/g' /usr/local/lib/node_modules/openclaw/dist/store-CA7OW_2w.js
    

    Correct - use environment variables or volume mounts

    docker run -e OPENCLAW_MEDIA_STAGING_MAX_BYTES=52428800 openclaw/app

  • npm Global Install vs. Local Install โ€” The bundle location differs:
    # Global install location
    $(npm root -g)/openclaw/dist/store-CA7OW_2w.js
    

    Local install location

    ./node_modules/openclaw/dist/store-CA7OW_2w.js

    Patching the wrong location causes the fix to appear ineffective.

  • Monorepo/workspace Configurations โ€” When OpenClaw is installed at the workspace root, nested packages may resolve a different bundle instance. Ensure all packages reference the same OpenClaw installation.
    # Check bundle resolution
    node -e "console.log(require.resolve('openclaw/dist/store-CA7OW_2w.js'))"

Configuration Edge Cases

  • Zero or Null Limit Values โ€” The fix must filter out non-positive values:
    # This should NOT be treated as unlimited
    channels:
      slack:
        media:
          maxBytes: 0  # Disables limit? Or error?
    

    Verify your fix handles this correctly

    openclaw config validate

    Should warn about invalid zero/null media limits

  • Channel-Specific Limits vs. Global Defaults โ€” The minimum of all limits is usually the correct effective limit, but some workflows may intend the maximum. Document the chosen semantics clearly.
  • Legacy Configuration Files โ€” Old .openclawrc JSON files may use mediaMaxBytes instead of media.maxBytes. Verify backward compatibility.

Runtime Behavior Pitfalls

  • Cached Bundle After Update โ€” After updating OpenClaw, clear the module cache:
    # Clear require cache in Node.js
    delete require.cache[require.resolve('openclaw/dist/store-CA7OW_2w.js')]
    

    Or restart the Node.js process entirely

  • Streaming Media Not Buffered โ€” If media is streamed (e.g., video generation), size validation may need to read the entire stream first. Ensure the fix handles both buffered and streaming scenarios.
  • Memory Pressure with Large Limits โ€” Setting staging limits very high (e.g., 500MB+) without corresponding memory configuration may cause OOM errors during staging operations.

Verification Failures

If verification tests fail unexpectedly:

  1. Confirm the bundle was actually updated (md5sum dist/store-CA7OW_2w.js)
  2. Check for multiple OpenClaw installations in the module resolution path
  3. Verify environment variables are being read correctly (console.log(process.env.OPENCLAW_MEDIA_STAGING_MAX_BYTES))
  4. Ensure the process has permission to read the updated bundle file

The following errors and issues are contextually related to the hardcoded 5MB staging limit:

  • MediaLimitError โ€” The primary error class thrown when media exceeds the staging threshold. May appear as "Media exceeds 5MB limit" or, after fixes, "Media exceeds {effectiveLimit} bytes".
  • MEDIA_EXCEEDS_CHANNEL_LIMIT โ€” A downstream error that occurs after staging if the channel-specific limit is still exceeded. This error should NOT occur if the staging limit is properly derived from channel configuration.
  • ENFILE / EMFILE (File Descriptor Limits) โ€” Not directly related but may surface when large media files are processed without proper streaming. Often confused with size limit errors.
  • EBADMSG (Message Not Processable) โ€” May occur if media validation fails partially due to size constraints before complete parsing. The 5MB limit may cause incomplete media objects to be passed downstream.
  • Issue: Silent Truncation of Media Metadata โ€” Related upstream issue where media metadata is stripped when size approaches the staging limit, causing downstream delivery failures with unclear error messages.
  • Issue: Video Generation Fails for Duration > ~15s โ€” Users report that video generation fails for longer durations, likely due to accumulated frame data exceeding the 5MB staging cap before the video is fully assembled.
  • Issue: Audio Files Stripped of Metadata โ€” Related to media staging behavior where high-bitrate audio files are partially processed, losing ID3/metadata tags when size validation is strict.
  • Upload payload too large โ€” Channel-specific errors from downstream integrations (Slack, Discord, etc.) that indicate the channel's actual limit was exceeded. If this error appears after the staging fix, the channel limit itself needs adjustment.
  • BufferOverflowError (Custom) โ€” May appear in custom OpenClaw deployments if the staging layer is extended without corresponding buffer size adjustments.
  • Historical: dist/store.js Renamed to dist/store-CA7OW_2w.js โ€” The bundle filename changed between versions. Ensure documentation references the correct current bundle name for the installed version.

Cross-Reference Matrix

Error/IssueLayerLimit SourceCan Override Staging?
Media exceeds 5MB limitStaging (bundled)Hardcoded constantNo (requires fix)
MEDIA_EXCEEDS_CHANNEL_LIMITChannel deliverychannel.media.maxBytesYes (config)
Upload payload too largeExternal APIPlatform limitNo
BufferOverflowErrorCustom/ExtendedCustom implementationDepends

Evidence & Sources

This troubleshooting guide was automatically synthesized by the FixClaw Intelligence Pipeline from community discussions.