Title: WP_Ability::prepare_properties
Published: February 24, 2026

---

# WP_Ability::prepare_properties( $args ): array<string,

## In this article

 * [Description](https://developer.wordpress.org/reference/classes/wp_ability/prepare_properties/?output_format=md#description)
    - [See also](https://developer.wordpress.org/reference/classes/wp_ability/prepare_properties/?output_format=md#see-also)
 * [Parameters](https://developer.wordpress.org/reference/classes/wp_ability/prepare_properties/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/classes/wp_ability/prepare_properties/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/classes/wp_ability/prepare_properties/?output_format=md#source)
 * [Related](https://developer.wordpress.org/reference/classes/wp_ability/prepare_properties/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/classes/wp_ability/prepare_properties/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/classes/wp_ability/prepare_properties/?output_format=md#wp--skip-link--target)

Prepares and validates the properties used to instantiate the ability.

## 󠀁[Description](https://developer.wordpress.org/reference/classes/wp_ability/prepare_properties/?output_format=md#description)󠁿

Errors are thrown as exceptions instead of WP_Errors to allow for simpler handling
and overloading. They are then caught and converted to a [WP_Error](https://developer.wordpress.org/reference/classes/wp_error/)
when by [WP_Abilities_Registry::register()](https://developer.wordpress.org/reference/classes/wp_abilities_registry/register/).

### 󠀁[See also](https://developer.wordpress.org/reference/classes/wp_ability/prepare_properties/?output_format=md#see-also)󠁿

 * [WP_Abilities_Registry::register()](https://developer.wordpress.org/reference/classes/WP_Abilities_Registry/register/)

## 󠀁[Parameters](https://developer.wordpress.org/reference/classes/wp_ability/prepare_properties/?output_format=md#parameters)󠁿

mixed> $args { An associative array of arguments used to instantiate the ability
class.
 @type string $label The human-readable label for the ability. @type string
$description A detailed description of what the ability does. @type string $category
The ability category slug this ability belongs to. @type callable $execute_callback
A callback function to execute when the ability is invoked. Receives optional mixed
input and returns mixed result or [WP_Error](https://developer.wordpress.org/reference/classes/wp_error/).
@type callable $permission_callback A callback function to check permissions before
execution. Receives optional mixed input and returns bool or [WP_Error](https://developer.wordpress.org/reference/classes/wp_error/).
@type array<string, mixed> $input_schema Optional. JSON Schema definition for the
ability’s input. Required if ability accepts an input. @type array<string, mixed
> $output_schema Optional. JSON Schema definition for the ability’s output. @type
array<string, mixed> $meta { Optional. Additional metadata for the ability. @type
array<string, `bool|null`> $annotations { Optional. Semantic annotations describing
the ability’s behavioral characteristics. These annotations are hints for tooling
and documentation. @type `bool|null` $readonly Optional. If true, the ability does
not modify its environment. @type `bool|null` $destructive Optional. If true, the
ability may perform destructive updates to its environment. If false, the ability
performs only additive updates. @type `bool|null` $idempotent Optional. If true,
calling the ability repeatedly with the same arguments will have no additional effect
on its environment. } @type bool $show_in_rest Optional. Whether to expose this 
ability in the REST API. Default false. } }

## 󠀁[Return](https://developer.wordpress.org/reference/classes/wp_ability/prepare_properties/?output_format=md#return)󠁿

 array<string, mixed> { An associative array of arguments with validated and prepared
properties for the ability class.
 @type string $label The human-readable label 
for the ability. @type string $description A detailed description of what the ability
does. @type string $category The ability category slug this ability belongs to. 
@type callable $execute_callback A callback function to execute when the ability
is invoked. Receives optional mixed input and returns mixed result or [WP_Error](https://developer.wordpress.org/reference/classes/wp_error/).
@type callable $permission_callback A callback function to check permissions before
execution. Receives optional mixed input and returns bool or [WP_Error](https://developer.wordpress.org/reference/classes/wp_error/).
@type array<string, mixed> $input_schema Optional. JSON Schema definition for the
ability’s input. @type array<string, mixed> $output_schema Optional. JSON Schema
definition for the ability’s output. @type array<string, mixed> $meta { Additional
metadata for the ability. @type array<string, `bool|null`> $annotations { Semantic
annotations describing the ability’s behavioral characteristics. These annotations
are hints for tooling and documentation. @type `bool|null` $readonly If true, the
ability does not modify its environment. @type `bool|null` $destructive If true,
the ability may perform destructive updates to its environment. If false, the ability
performs only additive updates. @type `bool|null` $idempotent If true, calling the
ability repeatedly with the same arguments will have no additional effect on its
environment. } @type bool $show_in_rest Whether to expose this ability in the REST
API. Default false. } }

## 󠀁[Source](https://developer.wordpress.org/reference/classes/wp_ability/prepare_properties/?output_format=md#source)󠁿

    ```php
    protected function prepare_properties( array $args ): array {
    	// Required args must be present and of the correct type.
    	if ( empty( $args['label'] ) || ! is_string( $args['label'] ) ) {
    		throw new InvalidArgumentException(
    			__( 'The ability properties must contain a `label` string.' )
    		);
    	}

    	if ( empty( $args['description'] ) || ! is_string( $args['description'] ) ) {
    		throw new InvalidArgumentException(
    			__( 'The ability properties must contain a `description` string.' )
    		);
    	}

    	if ( empty( $args['category'] ) || ! is_string( $args['category'] ) ) {
    		throw new InvalidArgumentException(
    			__( 'The ability properties must contain a `category` string.' )
    		);
    	}

    	if ( empty( $args['execute_callback'] ) || ! is_callable( $args['execute_callback'] ) ) {
    		throw new InvalidArgumentException(
    			__( 'The ability properties must contain a valid `execute_callback` function.' )
    		);
    	}

    	if ( empty( $args['permission_callback'] ) || ! is_callable( $args['permission_callback'] ) ) {
    		throw new InvalidArgumentException(
    			__( 'The ability properties must provide a valid `permission_callback` function.' )
    		);
    	}

    	// Optional args only need to be of the correct type if they are present.
    	if ( isset( $args['input_schema'] ) && ! is_array( $args['input_schema'] ) ) {
    		throw new InvalidArgumentException(
    			__( 'The ability properties should provide a valid `input_schema` definition.' )
    		);
    	}

    	if ( isset( $args['output_schema'] ) && ! is_array( $args['output_schema'] ) ) {
    		throw new InvalidArgumentException(
    			__( 'The ability properties should provide a valid `output_schema` definition.' )
    		);
    	}

    	if ( isset( $args['meta'] ) && ! is_array( $args['meta'] ) ) {
    		throw new InvalidArgumentException(
    			__( 'The ability properties should provide a valid `meta` array.' )
    		);
    	}

    	if ( isset( $args['meta']['annotations'] ) && ! is_array( $args['meta']['annotations'] ) ) {
    		throw new InvalidArgumentException(
    			__( 'The ability meta should provide a valid `annotations` array.' )
    		);
    	}

    	if ( isset( $args['meta']['show_in_rest'] ) && ! is_bool( $args['meta']['show_in_rest'] ) ) {
    		throw new InvalidArgumentException(
    			__( 'The ability meta should provide a valid `show_in_rest` boolean.' )
    		);
    	}

    	// Set defaults for optional meta.
    	$args['meta']                = wp_parse_args(
    		$args['meta'] ?? array(),
    		array(
    			'annotations'  => static::$default_annotations,
    			'show_in_rest' => self::DEFAULT_SHOW_IN_REST,
    		)
    	);
    	$args['meta']['annotations'] = wp_parse_args(
    		$args['meta']['annotations'],
    		static::$default_annotations
    	);

    	return $args;
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/abilities-api/class-wp-ability.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/6.9.4/src/wp-includes/abilities-api/class-wp-ability.php#L260)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/6.9.4/src/wp-includes/abilities-api/class-wp-ability.php#L260-L337)

## 󠀁[Related](https://developer.wordpress.org/reference/classes/wp_ability/prepare_properties/?output_format=md#related)󠁿

| Uses | Description | 
| [__()](https://developer.wordpress.org/reference/functions/__/)`wp-includes/l10n.php` |

Retrieves the translation of $text.

  | 
| [wp_parse_args()](https://developer.wordpress.org/reference/functions/wp_parse_args/)`wp-includes/functions.php` |

Merges user defined arguments into defaults array.

  |

| Used by | Description | 
| [WP_Ability::__construct()](https://developer.wordpress.org/reference/classes/wp_ability/__construct/)`wp-includes/abilities-api/class-wp-ability.php` |

Constructor.

  |

## 󠀁[Changelog](https://developer.wordpress.org/reference/classes/wp_ability/prepare_properties/?output_format=md#changelog)󠁿

| Version | Description | 
| [6.9.0](https://developer.wordpress.org/reference/since/6.9.0/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Fwp_ability%2Fprepare_properties%2F)
before being able to contribute a note or feedback.