Skip to content

Filesystem: Update constructor parameter default value to an empty array#11593

Open
Soean wants to merge 46 commits into
WordPress:trunkfrom
Soean:wp_fs_type
Open

Filesystem: Update constructor parameter default value to an empty array#11593
Soean wants to merge 46 commits into
WordPress:trunkfrom
Soean:wp_fs_type

Conversation

@Soean

@Soean Soean commented Apr 17, 2026

Copy link
Copy Markdown
Member

The constructor parameters of the WP_Filesystem_FTPext, WP_Filesystem_ftpsockets and WP_Filesystem_SSH2 classes should be an array not an empty string (''). We also should improve the doc block.

Trac ticket: https://core.trac.wordpress.org/ticket/65409


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@github-actions

github-actions Bot commented Apr 17, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props soean, westonruter, mukesh27.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

Comment thread src/wp-admin/includes/class-wp-filesystem-ftpext.php Outdated
@Soean

Soean commented Jun 4, 2026

Copy link
Copy Markdown
Member Author

Maybe we should also rename $opt to $options?

@westonruter

Copy link
Copy Markdown
Member

@Soean I've added a commit to address a wide array of PHPStan issues. On trunk, the following rule level 5 issues exist:

composer phpstan -- -c phpstan.neon.dist --level=5 src/wp-admin/includes/class-wp-filesystem*
 ------ -------------------------------------------------------------------- 
  Line   class-wp-filesystem-base.php                                        
 ------ -------------------------------------------------------------------- 
  443    Binary operation "+" between non-empty-string and non-empty-string  
         results in an error.                                                
         🪪  binaryOp.invalid                                                
         at src/wp-admin/includes/class-wp-filesystem-base.php:443           
  444    Binary operation "+" between non-empty-string and non-empty-string  
         results in an error.                                                
         🪪  binaryOp.invalid                                                
         at src/wp-admin/includes/class-wp-filesystem-base.php:444           
  445    Binary operation "+" between non-empty-string and non-empty-string  
         results in an error.                                                
         🪪  binaryOp.invalid                                                
         at src/wp-admin/includes/class-wp-filesystem-base.php:445           
 ------ -------------------------------------------------------------------- 

 ------ --------------------------------------------------------------------- 
  Line   class-wp-filesystem-direct.php                                       
 ------ --------------------------------------------------------------------- 
  25     Constructor of class WP_Filesystem_Direct has an unused parameter    
         $arg.                                                                
         🪪  constructor.unusedParameter                                      
         at src/wp-admin/includes/class-wp-filesystem-direct.php:25           
  253    Method WP_Filesystem_Direct::owner() should return string|false but  
         returns int<1, max>.                                                 
         🪪  return.type                                                      
         at src/wp-admin/includes/class-wp-filesystem-direct.php:253          
  298    Method WP_Filesystem_Direct::group() should return string|false but  
         returns int<1, max>.                                                 
         🪪  return.type                                                      
         at src/wp-admin/includes/class-wp-filesystem-direct.php:298          
 ------ --------------------------------------------------------------------- 

 ------ ----------------------------------------------------------------------- 
  Line   class-wp-filesystem-ftpext.php                                         
 ------ ----------------------------------------------------------------------- 
  22     Property WP_Filesystem_FTPext::$link has unknown class FTP\Connection  
         as its type.                                                           
         🪪  class.notFound                                                     
         💡  Learn more at https://phpstan.org/user-guide/discovering-symbols   
         at src/wp-admin/includes/class-wp-filesystem-ftpext.php:22             
  31     Default value of the parameter #1 $opt (string) of method              
         WP_Filesystem_FTPext::__construct() is incompatible with type array.   
         🪪  parameter.defaultValue                                             
         at src/wp-admin/includes/class-wp-filesystem-ftpext.php:31             
  656    Parameter #2 $min of function mktime expects int, string given.        
         🪪  argument.type                                                      
         at src/wp-admin/includes/class-wp-filesystem-ftpext.php:656            
  656    Parameter #4 $mon of function mktime expects int, string given.        
         🪪  argument.type                                                      
         at src/wp-admin/includes/class-wp-filesystem-ftpext.php:656            
  656    Parameter #5 $day of function mktime expects int, string given.        
         🪪  argument.type                                                      
         at src/wp-admin/includes/class-wp-filesystem-ftpext.php:656            
  719    Variable $b might not be defined.                                      
         🪪  variable.undefined                                                 
         at src/wp-admin/includes/class-wp-filesystem-ftpext.php:719            
 ------ ----------------------------------------------------------------------- 

 ------ ------------------------------------------------------------------- 
  Line   class-wp-filesystem-ftpsockets.php                                 
 ------ ------------------------------------------------------------------- 
  31     Default value of the parameter #1 $opt (string) of method          
         WP_Filesystem_ftpsockets::__construct() is incompatible with type  
         array.                                                             
         🪪  parameter.defaultValue                                         
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:31     
 ------ ------------------------------------------------------------------- 

 ------ ----------------------------------------------------------------------- 
  Line   class-wp-filesystem-ssh2.php                                           
 ------ ----------------------------------------------------------------------- 
  42     Property WP_Filesystem_SSH2::$link (resource) does not accept default  
         value of type false.                                                   
         🪪  property.defaultValue                                              
         at src/wp-admin/includes/class-wp-filesystem-ssh2.php:42               
  63     Default value of the parameter #1 $opt (string) of method              
         WP_Filesystem_SSH2::__construct() is incompatible with type array.     
         🪪  parameter.defaultValue                                             
         at src/wp-admin/includes/class-wp-filesystem-ssh2.php:63               
  421    Method WP_Filesystem_SSH2::owner() should return string|false but      
         returns int<1, max>.                                                   
         🪪  return.type                                                        
         at src/wp-admin/includes/class-wp-filesystem-ssh2.php:421              
  461    Method WP_Filesystem_SSH2::group() should return string|false but      
         returns int<1, max>.                                                   
         🪪  return.type                                                        
         at src/wp-admin/includes/class-wp-filesystem-ssh2.php:461              
 ------ ----------------------------------------------------------------------- 

 [ERROR] Found 17 errors                                                        

With the commit, the only error left at rule level 5 is:

Property WP_Filesystem_FTPext::$link has unknown class FTP\Connection as its type.

Now, clearly these changes could be out of scope here and could be reverted. However, by providing these additional types it is revealing possible bugs which were not previously detected. So maybe the scope should be increased to add the WP docs as well as the PHPStan docs for static analysis.

Comment thread src/wp-admin/includes/class-wp-filesystem-ftpsockets.php Outdated
Comment thread src/wp-admin/includes/class-wp-filesystem-ftpext.php Outdated
Comment thread src/wp-admin/includes/class-wp-filesystem-ssh2.php Outdated
Comment thread src/wp-admin/includes/class-wp-filesystem-ssh2.php Outdated
Soean and others added 5 commits June 9, 2026 13:44
Co-authored-by: Weston Ruter <westonruter@gmail.com>
Co-authored-by: Weston Ruter <westonruter@gmail.com>
Co-authored-by: Weston Ruter <westonruter@gmail.com>
Co-authored-by: Weston Ruter <westonruter@gmail.com>
Comment thread src/wp-admin/includes/class-wp-filesystem-ftpext.php
Comment thread src/wp-admin/includes/class-wp-filesystem-ftpsockets.php Outdated
Comment thread src/wp-admin/includes/class-wp-filesystem-ssh2.php
Comment thread src/wp-admin/includes/class-wp-filesystem-ssh2.php
@westonruter

Copy link
Copy Markdown
Member

All errors up to rule level 9 have been fixed. What remains are the following rule level 10 errors:

 ------ ----------------------------------------------------------------------- 
  Line   class-wp-filesystem-ftpsockets.php                                     
 ------ ----------------------------------------------------------------------- 
  274    Method WP_Filesystem_ftpsockets::put_contents() should return bool     
         but returns mixed.                                                     
         🪪  return.type                                                        
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:274        
  306    Method WP_Filesystem_ftpsockets::chdir() should return bool but        
         returns mixed.                                                         
         🪪  return.type                                                        
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:306        
  342    Method WP_Filesystem_ftpsockets::chmod() should return bool but        
         returns mixed.                                                         
         🪪  return.type                                                        
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:342        
  433    Method WP_Filesystem_ftpsockets::move() should return bool but         
         returns mixed.                                                         
         🪪  return.type                                                        
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:433        
  454    Method WP_Filesystem_ftpsockets::delete() should return bool but       
         returns mixed.                                                         
         🪪  return.type                                                        
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:454        
  458    Method WP_Filesystem_ftpsockets::delete() should return bool but       
         returns mixed.                                                         
         🪪  return.type                                                        
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:458        
  461    Method WP_Filesystem_ftpsockets::delete() should return bool but       
         returns mixed.                                                         
         🪪  return.type                                                        
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:461        
  581    Method WP_Filesystem_ftpsockets::mtime() should return int|false but   
         returns mixed.                                                         
         🪪  return.type                                                        
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:581        
  593    Method WP_Filesystem_ftpsockets::size() should return int|false but    
         returns mixed.                                                         
         🪪  return.type                                                        
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:593        
  720    Argument of an invalid type mixed supplied for foreach, only           
         iterables are supported.                                               
         🪪  foreach.nonIterable                                                
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:720        
  722    Cannot access offset 'name' on mixed.                                  
         🪪  offsetAccess.nonOffsetAccessible                                   
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:722        
  726    Cannot access offset 0 on mixed.                                       
         🪪  offsetAccess.nonOffsetAccessible                                   
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:726        
  734    Cannot access offset 'type' on mixed.                                  
         🪪  offsetAccess.nonOffsetAccessible                                   
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:734        
  736    Binary operation "." between string and mixed results in an error.     
         🪪  binaryOp.invalid                                                   
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:736        
  736    Cannot access offset 'files' on mixed.                                 
         🪪  offsetAccess.nonOffsetAccessible                                   
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:736        
  738    Cannot access offset 'files' on mixed.                                 
         🪪  offsetAccess.nonOffsetAccessible                                   
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:738        
  743    Cannot access offset 'islink' on mixed.                                
         🪪  offsetAccess.nonOffsetAccessible                                   
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:743        
  744    Cannot access offset 'name' on mixed.                                  
         🪪  offsetAccess.nonOffsetAccessible                                   
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:744        
  744    Cannot access offset 'name' on mixed.                                  
         🪪  offsetAccess.nonOffsetAccessible                                   
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:744        
  744    Parameter #3 $subject of function preg_replace expects array<float|in  
         t|string>|string, mixed given.                                         
         🪪  argument.type                                                      
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:744        
  748    Cannot access offset 'perms' on mixed.                                 
         🪪  offsetAccess.nonOffsetAccessible                                   
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:748        
  748    Cannot access offset 'permsn' on mixed.                                
         🪪  offsetAccess.nonOffsetAccessible                                   
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:748        
  748    Parameter #1 $mode of method WP_Filesystem_Base::getnumchmodfromh()    
         expects string, mixed given.                                           
         🪪  argument.type                                                      
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:748        
  750    Cannot access offset 'name' on mixed.                                  
         🪪  offsetAccess.nonOffsetAccessible                                   
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:750        
  750    Possibly invalid array key type mixed.                                 
         🪪  offsetAccess.invalidOffset                                         
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:750        
  755    Method WP_Filesystem_ftpsockets::dirlist() should return               
         array<string, array{name: string, perms?: string, permsn?: string,     
         number?: int|string|false, owner?: int<1, max>|string|false, group?:   
         int<1, max>|string|false, size: int|string|false, lastmodunix?:        
         int|string|false, ...}>|false but returns array.                       
         🪪  return.type                                                        
         at src/wp-admin/includes/class-wp-filesystem-ftpsockets.php:755        
 ------ ----------------------------------------------------------------------- 


 [ERROR] Found 26 errors                                                        

@westonruter

Copy link
Copy Markdown
Member

And there we have it! All PHPStan rule level 10 errors addressed.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the WordPress filesystem transport classes to use array-based constructor options (instead of an empty string default), and improves inline documentation/static-analysis types for filesystem listings and connection options.

Changes:

  • Update FTPext/ftpsockets/SSH2 constructors to accept null/arrays and document the supported option shapes (including PHPStan types).
  • Refine filesystem API docblocks/return types (e.g., get_contents_array() element types; add FileListing PHPStan shape in the base class).
  • Adjust some filesystem behaviors/guards (e.g., additional connection/resource checks) and update composer.json extension suggestions.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
src/wp-admin/includes/class-wp-filesystem-ssh2.php Constructor/doc/type updates; options handling; connection/auth logic; dirlist metadata typing.
src/wp-admin/includes/class-wp-filesystem-ftpsockets.php Constructor/doc/type updates; safer return typing; dirlist() handling adjustments.
src/wp-admin/includes/class-wp-filesystem-ftpext.php Constructor/doc/type updates; options handling; additional connection checks and typing refinements.
src/wp-admin/includes/class-wp-filesystem-direct.php Typing refinements for file listings and recursive chgrp/chown behavior.
src/wp-admin/includes/class-wp-filesystem-base.php Introduces PHPStan FileListing shape and improves various docblocks/typing.
composer.json Adds ext-ftp and ext-ssh2 to suggested extensions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/wp-admin/includes/class-wp-filesystem-ssh2.php Outdated
Comment thread src/wp-admin/includes/class-wp-filesystem-ssh2.php Outdated
Comment thread src/wp-admin/includes/class-wp-filesystem-direct.php Outdated
Comment thread src/wp-admin/includes/class-wp-filesystem-ftpsockets.php Outdated
Comment on lines +67 to +72
/**
* @since 7.1.0
* @var array
* @phpstan-var Options
*/
public $options;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋 Claude Code here. Same situation as the FTPext class — intentional, and explained in full there: #11593 (comment). TL;DR: omitting the default is what lets the narrowed @phpstan-var Options type attach (a default fails PHPStan level 10), and the null case is unreachable because WP_Filesystem() bails on errors->has_errors() before any method reads $this->options.

Comment on lines +32 to +37
/**
* @since 7.1.0
* @var array
* @phpstan-var Options
*/
public $options;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this (and the other duplicate such review comments from Copilot).

The purpose here is to document the type, but it's true that $options could be null if an error occurs when initializing the class.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋 Claude Code here, replying after digging into this.

This redeclaration intentionally omits the = array() default. The whole point of redeclaring $options in the subclass is to attach the narrowed @phpstan-var Options type, and there's no way to keep both a non-null default and the strict shape:

  • public $options = array(); with @phpstan-var Options fails PHPStan level 10 with property.defaultValue ("does not accept default value of type array{}"), because the shape's keys are required.
  • Widening to @phpstan-var Options|array{} makes the default valid but then regresses every unguarded read in connect() ($this->options['hostname'], etc.) with "offset might not exist on array{}". This one slips past phpstan-diff --changed because the reads are on unchanged lines, but a full level-10 run flags them.
  • A non-null constant default is impossible anyway, since hostname/username are non-empty-string — even '' wouldn't satisfy the type.

On the runtime "offset on null" risk: $this->options is only null on an errored, never-successfully-constructed instance. WP_Filesystem() checks $wp_filesystem->errors->has_errors() after construction and bails before connect() (or anything else that reads $this->options) is ever called, so the null-key access isn't reachable through supported usage. The strict Options type correctly describes the property as the consuming methods see it.

Leaving this as-is.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related hardening: 4921788

Comment thread src/wp-admin/includes/class-wp-filesystem-ftpsockets.php Outdated
Comment thread src/wp-admin/includes/class-wp-filesystem-ftpext.php Outdated
Comment thread src/wp-admin/includes/class-wp-filesystem-ssh2.php
Comment thread src/wp-admin/includes/class-wp-filesystem-ftpext.php Outdated
westonruter and others added 16 commits June 9, 2026 12:40
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…into wp_fs_type

* 'trunk' of https://github.com/WordPress/wordpress-develop:
  General: Add support for unicode email addresses in is_email and sanitize_email
  Media: Make image editor help icon scheme-aware.
  Media: Fix filter toolbar spinner alignment.
  Twenty Twenty: Add missing documentation for some global variables.
…ets.

Capture the current working directory before changing into the target
path so the FTP session's working directory is restored, rather than
capturing it afterward (which left the session in the target path and
made is_dir() no longer side-effect-free).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A username is mandatory for SSH authentication regardless of method:
ssh2_auth_pubkey_file() takes a required username argument, and the SSH
protocol authenticates a named user even when a key proves identity.

Previously the constructor only required a username for password auth, so
constructing with keys but no username produced no error, and connect()
would then silently skip authentication entirely. Validate the username
unconditionally so this surfaces a clear "SSH2 username is required" error,
and update the option type shapes to mark username as required.

With the username guaranteed, drop the now-redundant isset() guards for it
in connect(), along with the password isset/array_key_exists checks, using
null coalescing to satisfy the option type.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restore the public-key authentication branch to a plain else. Since
$this->keys is set true only when both public_key and private_key are
provided, the previous `elseif ( isset( ... ) )` was always true when
reached, and the unreachable third path meant connect() could fall through
to ssh2_sftp() with no authentication attempted at all.

Use null coalescing on the key paths to satisfy the option type shape,
which marks public_key and private_key as optional; the empty-string
fallbacks cannot occur at runtime, and would fail authentication safely
rather than skipping it if they ever did.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ets.

Handling the false return of the underlying ftp->dirlist() is correct, but
combining the path-existence check with OR changed behavior: a populated
listing was discarded whenever exists() disagreed (it probes via a separate
nlist() call with documented quirks). Restore the original semantics of
only erroring when the listing is empty AND the path does not exist, while
still treating an outright false as a failure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ails.

The new is_string() guard around the cwd() result left $base at its
incoming '.'/'' value when cwd() returns false (the FTP transports do this
on failure), changing the directory search root. Trunk derived $base from
trailingslashit( $this->cwd() ), which yielded '/' for a false cwd().
Preserve that behavior by falling back to '/' explicitly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread src/wp-admin/includes/class-wp-filesystem-ssh2.php Outdated
* @type string $password Optional. SSH password. May be empty when using keys.
* @type string $public_key Optional. Path to public key file for publickey authentication.
* @type string $private_key Optional. Path to private key file for publickey authentication.
* @type array $hostkey Optional. Hostkey options passed to ssh2_connect.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hostkey isn't actually an arg. It is an option that is computed by the public_key and private_key.

Suggested change
* @type array $hostkey Optional. Hostkey options passed to ssh2_connect.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 4921788

westonruter and others added 2 commits June 10, 2026 16:11
The FTP/SSH2 subclasses now assign $this->options only when the constructor
records no errors, so a failed construction leaves $this->options null
rather than the base class's array() default. Calling connect() directly on
such an object (bypassing the has_errors() check WP_Filesystem() performs)
would then access an offset on null. Guard each connect() with an early
return when errors are present, matching the check in WP_Filesystem().

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The FileListing shape and the dirlist() @type docs declared time as
string|false, but the FTP transports build it from mktime()/strtotime() in
parselisting(), i.e. an integer Unix timestamp, while Direct and SSH2 format
it as a gmdate() string. Widen the shared shape to int|string|false and note
in the docs that FTP transports return a timestamp, so the type reflects the
actual data across transports.

Also harden the ftpsockets dirlist() consumer to guard the untyped PemFTP
ftp::dirlist() return with is_array() rather than a strict false check, so an
unexpected non-array return is handled instead of trusted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@westonruter westonruter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Soean aside from maybe adding some tests, I think this is good to go, if you concur.

@westonruter

Copy link
Copy Markdown
Member

@Soean are you happy with this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants