thephpleague/flysystem · error · InvalidStreamProvided

Invalid stream provided, expected stream resource, received

Error message

Invalid stream provided, expected stream resource, received {type}

What it means

Filesystem::writeStream() validates its $contents argument with assertIsResource(): it must be a PHP stream resource. If is_resource() is false (you passed a string, null, array, object, bool, int), an InvalidStreamProvided exception is thrown with the received type from gettype(). This is a developer API-contract error, not an I/O error.

Source

Thrown at src/Filesystem.php:262

                is_array($publicUrl) => new ShardedPrefixPublicUrlGenerator($publicUrl),
                default => new PrefixPublicUrlGenerator($publicUrl),
            };
        }

        if ($this->adapter instanceof PublicUrlGenerator) {
            return $this->adapter;
        }

        return null;
    }

    /**
     * @param mixed $contents
     */
    private function assertIsResource($contents): void
    {
        if (is_resource($contents) === false) {
            throw new InvalidStreamProvided(
                "Invalid stream provided, expected stream resource, received " . gettype($contents)
            );
        } elseif (($type = get_resource_type($contents)) !== 'stream') {
            throw new InvalidStreamProvided(
                "Invalid stream provided, expected stream resource, received resource of type " . $type
            );
        }
    }

    /**
     * @param resource $resource
     */
    private function rewindStream($resource): void
    {
        if (ftell($resource) !== 0 && stream_get_meta_data($resource)['seekable']) {
            rewind($resource);
        }
    }

View on GitHub (pinned to b277b5dc3d)

Solutions

  1. Pass a stream resource: $stream = fopen($file, 'rb'); then $filesystem->writeStream($path, $stream);.
  2. If you have a string, use writeStream with php://memory (stream_get_contents) or simply call write().
  3. If you have a PSR-7 StreamInterface, call ->detach() to obtain the underlying resource.
  4. Check fopen() for false before using it so a failed open doesn't cascade into this error.

Example fix

// before
$filesystem->writeStream('dest.txt', file_get_contents('/tmp/source.txt')); // string -> throws

// after
$stream = fopen('/tmp/source.txt', 'rb');
if ($stream === false) {
    throw new RuntimeException('Unable to open source file.');
}
$filesystem->writeStream('dest.txt', $stream);
fclose($stream);
Defensive patterns

Strategy: type-guard

Validate before calling

if ( ! is_resource($contents)) {
    throw new InvalidArgumentException('writeStream() requires a stream resource; use write() for strings.');
}

Type guard

/**
 * Narrow a value to a valid open stream resource for Flysystem writeStream().
 */
function isStreamResource(mixed $value): bool
{
    return is_resource($value) && get_resource_type($value) === 'stream';
}

Try / catch

use League\Flysystem\InvalidStreamProvided;

try {
    $filesystem->writeStream($path, $contents);
} catch (InvalidStreamProvided $e) {
    // programmer error: fix the call site, do not retry
    throw new InvalidArgumentException($e->getMessage(), 0, $e);
}

Prevention

When it happens

Trigger: Calling $filesystem->writeStream($path, file_get_contents($file)) (string); passing a PSR-7 StreamInterface object (e.g. Guzzle stream); passing null/false from a failed fopen(); forwarding a variable that was never opened as a stream.

Common situations: Refactoring write() code to writeStream() without switching file_get_contents to fopen; consuming HTTP bodies and passing response stream objects; forgot that write() takes strings but writeStream() takes resources.

Related errors


AI-assisted analysis of thephpleague/flysystem@b277b5dc3d (2026-08-17). Data as JSON: /api/errors/a9db37e875c1fb68. Report an issue: GitHub.