apify/crawlee · error · Error

"${segment}" is not allowed because it would resolve outside

Error message

"${segment}" is not allowed because it would resolve outside of the storage directory. Storage names and record keys must not contain path traversal segments ("..") or absolute paths.

What it means

resolveWithinDirectory joins a user-supplied name/key onto a base storage directory and verifies the result stays inside that base. This guards the memory-storage implementation against path traversal: names containing '..' or absolute paths could read/write files outside the storage directory. Any storage name, queue id, or record key that escapes the base is rejected.

Source

Thrown at packages/core/src/memory-storage/utils.ts:16

import { createHash } from 'node:crypto';
import { resolve, sep } from 'node:path';

import { REQUEST_ID_LENGTH } from './consts.js';

/**
 * Resolves `segment` against `baseDirectory` and ensures the result stays within `baseDirectory`.
 * Storage names and record keys are used as filesystem path components, so a value containing `..`
 * or an absolute path could otherwise escape the intended directory.
 */
export function resolveWithinDirectory(baseDirectory: string, segment: string): string {
    const base = resolve(baseDirectory);
    const resolved = resolve(base, segment);

    if (resolved !== base && !resolved.startsWith(`${base}${sep}`)) {
        throw new Error(
            `"${segment}" is not allowed because it would resolve outside of the storage directory. ` +
                `Storage names and record keys must not contain path traversal segments ("..") or absolute paths.`,
        );
    }

    return resolved;
}

/**
 * Removes all properties with a null value
 * from the provided object.
 */
export function purgeNullsFromObject<T>(object: T): T {
    if (object && typeof object === 'object' && !Array.isArray(object)) {
        for (const [key, value] of Object.entries(object)) {
            if (value === null) Reflect.deleteProperty(object as Record<string, unknown>, key);
        }
    }

View on GitHub (pinned to dbe57fb09c)

Solutions

  1. Sanitize the name/key: strip or reject '..' segments, leading '/', and drive letters before passing it.
  2. Use only alphanumeric, dash, and underscore characters for storage names and record keys.
  3. If nested organization is needed, create separate storages instead of encoding paths in the name.
  4. Validate untrusted input at the boundary (e.g. a schema with a regex like /^[A-Za-z0-9_-]+$/).

Example fix

// before
const store = await MemoryStorage.openStore(userInput); // '../other'
// after
const name = userInput.replace(/[^A-Za-z0-9_-]/g, '');
if (!name) throw new Error('Invalid storage name');
const store = await MemoryStorage.openStore(name);
Defensive patterns

Strategy: validation

Validate before calling

function isSafeStorageName(name) {
  return typeof name === 'string' && /^[A-Za-z0-9_-]+$/.test(name);
}
if (!isSafeStorageName(userInput)) throw new Error('Invalid storage name');

Type guard

function isSafeStorageSegment(s: unknown): s is string {
  return typeof s === 'string' && s.length > 0 && !s.includes('..') && !s.startsWith('/') && !s.includes('\\') && /^[A-Za-z0-9_-]+$/.test(s);
}

Try / catch

try {
  return resolveWithinDirectory(base, segment);
} catch (err) {
  if ((err as Error).message.includes('would resolve outside of the storage directory')) {
    throw new ValidationError(`Unsafe storage key: ${segment}`);
  }
  throw err;
}

Prevention

When it happens

Trigger: Passing a storage name or record key containing '..' (e.g. '../secrets'), an absolute path ('/etc/passwd'), or on Windows a drive-qualified path to MemoryStorage APIs such as opening a store/queue/dataset with such a name, or accessing a record whose key resolves outside the base directory.

Common situations: User-supplied storage names passed straight from input into MemoryStorage; keys built by string concatenation with unsanitized segments; attempting to alias one store to another path via traversal; security testing of crawlee memory storage.

Related errors


AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30). Data as JSON: /api/errors/af5ba8aff04902f9. Report an issue: GitHub.