rohitg00/agentmemory · error · Error

Refusing to read image outside managed store: ${data.raw.ima

Error message

Refusing to read image outside managed store: ${data.raw.imageData}

What it means

The compress function can accept either inline base64 image data or a path to an image previously stored in agentmemory's managed store. For security, arbitrary filesystem paths are refused unless isManagedImagePath() confirms the path lives inside the managed store. This prevents the function from being used to read arbitrary files and encode them as base64.

Source

Thrown at src/functions/compress.ts:91

  sdk.registerFunction("mem::compress", 
    async (data: {
      observationId: string;
      sessionId: string;
      raw: RawObservation;
    }) => {
      const startMs = Date.now();

      let imageDescription: string | undefined;
      const hasImage = data.raw.modality === "image" || data.raw.modality === "mixed";

      if (hasImage && data.raw.imageData && provider.describeImage) {
        try {
          let base64Data = data.raw.imageData;
          let mimeType = "image/png";

          if (!data.raw.imageData.startsWith("/9j/") && !data.raw.imageData.startsWith("iVBOR")) {
            if (!isManagedImagePath(data.raw.imageData)) {
              throw new Error(`Refusing to read image outside managed store: ${data.raw.imageData}`);
            }
            const fileBuffer = readFileSync(data.raw.imageData);
            base64Data = fileBuffer.toString("base64");
            if (data.raw.imageData.endsWith(".jpg") || data.raw.imageData.endsWith(".jpeg")) mimeType = "image/jpeg";
            else if (data.raw.imageData.endsWith(".webp")) mimeType = "image/webp";
            else if (data.raw.imageData.endsWith(".gif")) mimeType = "image/gif";
          }

          imageDescription = await provider.describeImage(base64Data, mimeType, VISION_DESCRIPTION_PROMPT);
          logger.info("Image described by vision model", { obsId: data.observationId });
        } catch (err) {
          const msg = err instanceof Error ? err.message : String(err);
          logger.warn("Vision model call failed, falling back to text-only compression", {
            obsId: data.observationId,
            error: msg,
          });
        }
      }

View on GitHub (pinned to e04ba88819)

Solutions

  1. Read the file yourself and pass its base64 content in raw.imageData instead of a path.
  2. Store the image through the managed image write path first, then pass the returned managed path.
  3. Verify the path is inside the configured managed store directory (check isManagedImagePath logic / data dir).
  4. Ensure you're on a consistent agentmemory version so the managed store location matches.

Example fix

// before
await trigger({ function_id: 'mem::compress', payload: { raw: { imageData: '/tmp/shot.png' } } });
// after
const b64 = readFileSync('/tmp/shot.png').toString('base64');
await trigger({ function_id: 'mem::compress', payload: { raw: { imageData: b64 } } });
Defensive patterns

Strategy: validation

Validate before calling

function isInlineBase64Image(s: string): boolean {
  return s.startsWith('/9j/') || s.startsWith('iVBOR');
}
function toPayload(raw: string) {
  if (isInlineBase64Image(raw)) return { imageData: raw };
  const b64 = readFileSync(resolveManagedPath(raw)).toString('base64');
  return { imageData: b64 };
}

Type guard

function isInlineImageData(v: unknown): v is string {
  return typeof v === 'string' && (v.startsWith('/9j/') || v.startsWith('iVBOR'));
}

Try / catch

try {
  return await trigger({ function_id: 'mem::compress', payload: { raw } });
} catch (e) {
  if (String(e.message).includes('Refusing to read image outside managed store')) {
    return await compressViaBase64(raw);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling mem::compress with raw.imageData set to a filesystem path (e.g. /home/user/photo.png, or a relative path) that is not inside the managed image store, and whose content does not begin with JPEG ('/9j/') or PNG ('iVBOR') base64 magic prefixes.

Common situations: Passing a local screenshot path instead of reading the file yourself; hardcoding an absolute path that worked before the managed-store restriction was added (version change); moving/renaming the data directory so the path is no longer recognized as managed.

Related errors


AI-assisted analysis of rohitg00/agentmemory@e04ba88819 (2026-08-30). Data as JSON: /api/errors/718e9f47e19b28bc. Report an issue: GitHub.