laravel/framework · error · InvalidArgumentException

Cache value for key [%s] must be a string, %s given.

Error message

Cache value for key [%s] must be a string, %s given.

What it means

Thrown by Cache\Repository::string() when the value stored under the given key is not a string. The method calls get() then asserts is_string(); null (the implicit default for a missing key) also fails the check. It exists so typed cache accessors fail loudly instead of silently returning the wrong type.

Source

Thrown at src/Illuminate/Cache/Repository.php:250

        });
    }

    /**
     * Retrieve a string item from the cache.
     *
     * @param  \UnitEnum|string  $key
     * @param  (\Closure():(string|null))|string|null  $default
     *
     * @throws \InvalidArgumentException
     */
    public function string($key, $default = null): string
    {
        $key = enum_value($key);

        $value = $this->get($key, $default);

        if (! is_string($value)) {
            throw new InvalidArgumentException(
                sprintf('Cache value for key [%s] must be a string, %s given.', $key, gettype($value))
            );
        }

        return $value;
    }

    /**
     * Retrieve an integer item from the cache.
     *
     * @param  \UnitEnum|string  $key
     * @param  (\Closure():(int|null))|int|null  $default
     *
     * @throws \InvalidArgumentException
     */
    public function integer($key, $default = null): int
    {
        $key = enum_value($key);

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. Pass a string default: Cache::string('key', '') so missing keys resolve to a string.
  2. Verify the writer: ensure Cache::put('key', (string) $value) is used wherever this key is stored.
  3. Switch to Cache::get('key') and cast/validate manually if the value type legitimately varies.
  4. Clear the stale entry with Cache::forget('key') after correcting the writer.

Example fix

// before
$name = Cache::string('user.name');

// after
$name = Cache::string('user.name', '');
// or fix the writer
Cache::put('user.name', (string) $user->name, now()->addHour());
Defensive patterns

Strategy: type-guard

Validate before calling

$value = Cache::get('user.name');
if (! is_string($value)) {
    // resolve missing/wrong type before calling Cache::string()
    $value = '';
}

Type guard

function isCachedString(string $key): bool {
    return is_string(Cache::get($key));
}

Try / catch

try {
    $name = Cache::string('user.name');
} catch (\InvalidArgumentException $e) {
    // log and fall back
    $name = (string) Cache::get('user.name', '');
}

Prevention

When it happens

Trigger: Calling Cache::string('key') or $repository->string('key') when the stored value is an int/array/object/bool, or when the key does not exist and no string $default was supplied (null default → 'NULL given').

Common situations: Config/env value cached as integer then read with string(); cache key typo or stale entry written by an older code path that stored a serialized object; forgetting that a missing key yields null.

Related errors


AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06). Data as JSON: /data/errors/c84b5edf6f0d0575.json. Report an issue: GitHub.