Matlab Validate Function Arguments
MathWorksOfficialCreated by MathWorks
- Skill
- Tool integration
- Software development
- BSD-2-Clause
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a comprehensive guide to using MATLAB's arguments blocks for defensive programming. It covers the implementation of input validation, size and class constraints, repeating arguments, and name-value argument handling. It also details how to migrate legacy input parsing methods to modern syntax and provides patterns for constructor property imports and argument forwarding.
What it does
- Defines input validation contracts using arguments blocks
- Enforces size, class, and value constraints on function inputs
- Implements repeating argument patterns for variable input groups
- Imports class properties as name-value arguments using .?ClassName syntax
- Provides migration paths from inputParser and validateattributes
- Handles name-value argument forwarding with namedargs2cell
When to use it
- When writing new MATLAB functions requiring robust input checking
- When migrating legacy code from inputParser or validateattributes
- When creating class constructors that accept name-value pairs
- When functions need to handle variable-length input groups
- When you need to ensure function inputs meet specific size or type criteria
Advantages
- Eliminates manual input parsing boilerplate
- Provides clear, declarative function signatures
- Enables automatic tab completion for name-value arguments
- Reduces runtime errors through early input rejection
- Simplifies constructor maintenance via property synchronization
Usage examples
- “How do I restrict a function input to a positive integer scalar in an arguments block?”
- The agent provides an arguments block with the validator {mustBeInteger, mustBePositive} applied to a (1,1) variable.
- “How can I import all public properties of my class into a constructor as name-value arguments?”
- The agent demonstrates the use of the .?ClassName syntax within an arguments block to automatically expose properties.
- “How do I handle variable groups of x and y coordinates in a plotting function?”
- The agent shows how to use arguments (Repeating) to define x and y as cell arrays, allowing for multiple series inputs.
- “Why is my function accepting column vectors when I specified (1,:) in the arguments block?”
- The agent explains that (1,:) performs implicit reshaping and suggests using the mustBeRow validator to strictly reject column vectors.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/matlab/matlab-validate-function-arguments/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip matlab-validate-function-arguments.zip -d .agents/skills
Documentation by MathWorks
MATLAB Function Argument Validation
Write robust MATLAB functions using arguments blocks with correct semantics for size, class, repeating arguments, and property import.
When to Use
Writing a function with an
argumentsblockUsing repeating arguments (
arguments (Repeating))Writing a class constructor that accepts name-value arguments
Migrating from
inputParserorvalidateattributesReviewing a function signature for implicit conversion pitfalls
Choosing between class specs,
mustBeA, and validators
When NOT to Use
Basic MATLAB programming without argument validation
App building or UI components (use
matlab-build-app)Unit testing (use
matlab-write-tests)General OOP class design unrelated to argument validation
Simple
if/errorguard clauses for runtime invariants inside a function body (those aren't input validation — leave them as-is unless the user asks for anargumentsblock specifically).mlx(Live Script) or.mlapp(App Designer) files — these are binary ZIP containers. Don't unzip them or attempt structural edits. If the user asks to add anargumentsblock to a function inside one, ask them to export to plain.mfirst, or open the file in MATLAB and edit it there.
Critical Misconceptions
These are things the agent commonly gets wrong. Read these FIRST.
Size specs RESHAPE, not reject
WRONG belief: (1,:) rejects column vectors with an error.
ACTUAL behavior: MATLAB silently reshapes the input to fit the declared size.
function out = myFunc(x)
arguments
x (1,:) double
end
out = x;
end
myFunc([1; 2; 3]) % Does NOT error! Returns [1 2 3] (reshaped to row)A column vector [1;2;3] passed to (1,:) becomes a row vector [1 2 3]. To actually reject column vectors, use a validator:
function out = myFunc(x)
arguments
x {mustBeNumeric, mustBeRow}
end
out = x;
endClass specs CONVERT, not reject
WRONG belief: double in the arguments block rejects non-double inputs.
ACTUAL behavior: MATLAB attempts implicit conversion to the declared class.
function out = myFunc(x)
arguments
x double
end
out = x;
end
myFunc('hello') % Does NOT error! Returns [104 101 108 108 111] (ASCII codes)
myFunc(single(3.14)) % Does NOT error! Returns double(3.14)To reject without converting, use mustBeA or mustBeFloat:
x {mustBeA(x, "double")} % Rejects single, char, int32, etc.
x {mustBeFloat} % Accepts single OR double, rejects char/int
x {mustBeNumeric} % Accepts any numeric, rejects char/stringNumeric validators don't reject complex values
WRONG belief: mustBeNumeric, mustBeFinite, and mustBeInteger reject
complex inputs like 1+2i.
ACTUAL behavior: Complex values are numeric, finite, and (when their real
and imaginary parts are integer-valued) integer — so 1+2i passes all three
silently. Sizes, indices, counts, and most physical scalars should reject
complex values explicitly:
function H = hilb2(n)
arguments
n (1,1) {mustBeInteger, mustBePositive, mustBeReal}
end
H = 1./((1:n)' + (0:n-1));
endAdd mustBeReal whenever a complex input would be nonsensical for the
function's contract.
Computed defaults see PASSED values, not declared defaults
WRONG belief: Default expressions use the declared default values of earlier arguments.
ACTUAL behavior: Default expressions evaluate using the actual passed values.
function out = myFunc(fs, windowSize)
arguments
fs (1,1) double {mustBePositive}
windowSize (1,1) double {mustBePositive} = round(fs / 10)
end
out = windowSize;
end
myFunc(8000) % windowSize = round(8000/10) = 800 (uses passed fs)
myFunc(8000, 256) % windowSize = 256 (explicitly passed)This eliminates the need for sentinel values ([]) and post-validation fixup.
~ is a valid placeholder — don't rename it
WRONG belief: A name in the arguments block is mandatory, so a ~
placeholder in the function signature must be renamed to obj/this/etc.
ACTUAL behavior: ~ is valid as an argument-block name (R2019b+). Keep it.
function normalize(~, results)
arguments
~
results (1,:) struct
end
...
endWhen a method signature uses ~ to mark an unused input (e.g. an unused
class instance), preserve the ~ in the arguments block:
No class or size spec on
~— type specs like(1,1) MetricCalculatorrequire a name, so adding one forces a rename. Skip the spec entirely.No
%#ok<INUSL>/%#ok<INUSA>/%#ok<MANU>pragma —~already tells the lint pass the input is intentionally unused.Don't rename
~toobjto "tighten validation." Renaming reintroduces the lint warning the original~was suppressing, with no contract benefit.
Patterns
Repeating Arguments
Use arguments (Repeating) for functions accepting variable groups of arguments (like plot(x1,y1,x2,y2,...)). Each declared variable becomes a cell array in the function body.
function plotMultiSeries(x, y)
arguments (Repeating)
x (1,:) double {mustBeFinite}
y (1,:) double {mustBeFinite}
end
figure;
hold on;
for i = 1:numel(x)
plot(x{i}, y{i});
end
hold off;
endKey rules:
Variables become cell arrays — access with
x{i}, notx(i)All variables in the group repeat together (complete sets)
Repeating arguments cannot have default values
Zero repetitions is valid (produces empty cell arrays)
Output Argument Validation — arguments (Output) and (Output, Repeating)
R2022b+. Output argument validation is unavailable in earlier releases — input validation (the bulk of this skill) works from R2019b onward.
Use arguments (Output, Repeating) to declare a function whose output count
scales with nargout. The block must declare exactly one name — MATLAB
rejects multi-name repeating output blocks with
MATLAB:functionValidation:MultipleRepeatingOutputs. To return groups of
related values (e.g. triples), pack them into the single output and have the
caller request N * groupSize outputs.
function out = productTriples()
arguments (Output, Repeating)
out (1,1) double
end
out = cell(1, nargout);
for k = 1:3:nargout
b = rand;
c = rand;
out{k} = b * c;
out{k+1} = b;
out{k+2} = c;
end
endCaller: [p1, a1, b1, p2, a2, b2] = productTriples();
Key rules:
One name only —
arguments (Output, Repeating) a; b; c; enderrors at parseThe output is assigned a
1×nargoutcell array; comma-list expansion at the call site distributes its contents across the requested LHS variablesValidators on the single declared name apply to each cell element
nargouttells the body how many outputs were requested; zero is valid
Composition Rules — What Can Coexist
A function may have multiple arguments blocks. The rules below apply to
the function as a whole — argument categories must appear in this order across
all blocks combined:
required → optional (with defaults) → repeating → name-valueViolating the order at any point — even across separate blocks — fails to parse. Don't trust intuition: all of these compose legally in one function:
required + optional + repeating + name-value (
.?ClassNameallowed too)required + repeating + name-value
repeating + name-value
(Output, Repeating)plus any combination of input blocks~placeholders inside a(Repeating)block
Multiplicity:
| Block kind | How many allowed |
|---|---|
Plain arguments (positional and/or name-value) | Multiple, in order |
arguments (Repeating) (input) | Exactly one per function |
arguments (Output, Repeating) | Exactly one per function |
| Name-value structs across plain blocks | Multiple — different struct names |
Parse-time error identifiers — when in doubt, write the function and let MATLAB tell you. These are the only errors composition can produce; the names spell out the rule:
| Identifier | Means |
|---|---|
MATLAB:functionValidation:RequiredAfterOptional | A required arg appears after one with a default |
MATLAB:functionValidation:OptionalAfterRepeating | An optional/positional arg appears after the repeating block |
MATLAB:functionValidation:PositionalAfterNamed | A positional or repeating arg appears after a name-value arg |
MATLAB:functionValidation:MultipleRepeatingBlocks | More than one (Repeating) block (input or output) |
MATLAB:functionValidation:RepeatingHasDefault | A (Repeating) arg has a default value |
If you're unsure whether a combination is legal, don't fabricate a restriction — write a minimal version and run it. The error identifier (or its absence) is the answer.
Maximal example
A single function with required + optional + ignored + repeating + ignored
repeating + name-value + class-imported name-value (here SensorConfig —
the class defined in the .?ClassName section above):
function maximal(req, opt, ~, x, ~, options, classArg)
arguments
req (1,1) double
opt (1,1) double = 7
~
end
arguments (Repeating)
x (1,1) double
~
end
arguments
options.Title (1,1) string = "default"
options.Verbose (1,1) logical = false
classArg.?SensorConfig
end
% function body
endCall: maximal(1, 2, 3, 4, 'a', 5, 'b', Title="t", SampleRate=44100) —
parses and runs. SampleRate is one of the name-value args imported from
SensorConfig by the .? line.
Don't pick a class with no public-settable properties for .?ClassName —
onCleanup, for example, has only task (private set), so .?onCleanup
imports zero name-value args. The line is syntactically valid but a no-op,
and any "name-value" the caller writes against it is treated as an unknown
name — see "unknown Name=Value is silently swallowed" in Common Mistakes.
For combining repeating args with name-value options, see the Maximal example above and references/examples/repeating-args.md.
.?ClassName — Import Properties as Name-Value Args
Use .?ClassName in constructors to derive name-value arguments directly from property definitions. This avoids redeclaring properties in the arguments block.
For additional patterns — overriding specific properties, static factory with forwarding, and wrapping graphics-class properties — see references/examples/dot-question-syntax.md.
classdef SensorConfig
properties
SampleRate (1,1) double {mustBePositive} = 1000
Resolution (1,1) double {mustBePositive, mustBeInteger} = 16
FilterOrder (1,1) double {mustBePositive, mustBeInteger} = 4
Label (1,1) string = "unnamed"
end
methods
function obj = SensorConfig(nvArgs)
arguments
nvArgs.?SensorConfig
end
props = fieldnames(nvArgs);
for i = 1:numel(props)
obj.(props{i}) = nvArgs.(props{i});
end
end
end
endBenefits:
No duplication of size, class, validators, or defaults
Constructor stays in sync when properties are added or removed
Tab completion shows all settable properties automatically
namedargs2cell — Forward Name-Value Args
Use namedargs2cell to convert a validated struct back to a name-value cell array for forwarding to other functions:
function obj = fromPreset(presetName, nvArgs)
arguments
presetName (1,1) string
nvArgs.?SensorConfig
end
switch presetName
case "audio"
defaults = struct(SampleRate=44100, Resolution=24, Label="audio");
case "vibration"
defaults = struct(SampleRate=10000, Resolution=16, Label="vibration");
end
% Apply overrides
overrides = fieldnames(nvArgs);
for i = 1:numel(overrides)
defaults.(overrides{i}) = nvArgs.(overrides{i});
end
args = namedargs2cell(defaults);
obj = SensorConfig(args{:});
endMigration Decision Framework
When migrating from inputParser or validateattributes, use this decision tree for class handling:
| Original check | What it does | Arguments block equivalent | Why |
|---|---|---|---|
@isnumeric | Accepts any numeric, no conversion | {mustBeNumeric} | No class spec — avoids conversion |
@ischar | Accepts char only | {mustBeA(label, 'char')} or (1,:) char | mustBeText/mustBeTextScalar widens to accept string |
@islogical | Accepts logical only | (1,1) {mustBeA(x, 'logical')} | A logical class spec CONVERTS — logical(1) → true, so 1/0 (and other convertible scalars) would be accepted where @islogical rejects them. Use mustBeA (no class spec) to reject without converting. |
{'numeric'} | Accepts any numeric, no conversion | {mustBeNumeric} | validateattributes meta-class — same set as @isnumeric |
{'float'} | Accepts single or double | {mustBeFloat} | Equivalent to {'single','double'} |
{'integer'} (class spec, rare) | Accepts only integer types (int8…uint64) | Usually {mustBeNumeric, mustBeInteger}. Strict-only-if-intentional: {mustBeA(x, ["int8","int16","int32","int64","uint8","uint16","uint32","uint64"])} | The class-only form rejects integer-valued doubles like 5.0 — usually accidental. Widen to the lenient pairing unless the original code clearly meant to reject doubles. |
{'numeric'}, {'integer'} (class+attr) | Numeric, integer-valued | {mustBeNumeric, mustBeInteger} | Common pairing — accepts both int types and integer-valued floats |
{'single','double'} | Restricts to float types | {mustBeFloat} | Class spec double would convert single→double |
{'double'} exact | Rejects single, int, char | {mustBeA(x, "double")} | Class spec double would convert, not reject |
@(x) isa(x,'MyClass') | Class membership | {mustBeA(x, "MyClass")} | Validates without conversion |
Key principle: If the original code REJECTS mismatched types, use validators (mustBeA, mustBeFloat, mustBeNumeric). If you WANT automatic conversion for caller convenience, use a class spec.
Anonymous-Function Validators
Don't drop these on migration — each has a built-in equivalent:
inputParser validator | Arguments block equivalent |
|---|---|
@(x) ~isempty(x) | {mustBeNonempty} |
@(x) x > 0 | {mustBePositive} |
@(x) x >= 0 | {mustBeNonnegative} |
@(x) x < 0 | {mustBeNegative} |
@(x) x <= 0 | {mustBeNonpositive} |
@(x) isfinite(x) | {mustBeFinite} |
@(x) isreal(x) | {mustBeReal} |
@(x) isnumeric(x) && isreal(x) | {mustBeNumeric, mustBeReal} |
@(x) ismember(x, set) | {mustBeMember(x, set)} |
validatestring(x, set) | Don't replace with mustBeMember. validatestring does case-insensitive prefix matching and returns the canonical form; mustBeMember is exact-match only. Keep the call inside the body and use the arguments block only for {mustBeTextScalar}. |
For detailed migration examples, see references/migration-guide.md.
Conventions
Prefer
stringovercharfor new code (not migrations)Never use
vararginwith manual parsing whenarguments (Repeating)or name-value blocks can express the same interfaceUse
.?ClassNamein constructors rather than redeclaring propertiesPrefer computed defaults (
= expression) over sentinel values withisemptychecks, when the default depends only on earlier argumentsDon't combine
mustBeNumericwith adoubleclass spec to reject non-numeric input — the class spec converts char ('A'→65) before the validator runs, defeating the check. Drop the class spec:x {mustBeNumeric}notx (1,1) double {mustBeNumeric}Don't combine text validators with a
stringclass spec — the class spec converts non-text (e.g.,42→"42") before the validator runs, defeating the check. Use text validators alone:p {mustBeTextScalar}notp (1,1) string {mustBeTextScalar}Never reach for
varargin+ manualclass()checks to reject types. When a class spec likedoublewould convert (rather than reject) char/single/int input, the right answer is a validator (mustBeNumeric,mustBeFloat,mustBeA), not a fallback tovarargin. Falling back tovarargindefeats the entire point of the arguments block.
Common Mistakes
| Mistake | Why It's Wrong | Correct Approach |
|---|---|---|
Using varargin for repeated arg groups | Requires 30+ lines of manual parsing | arguments (Repeating) — 3 lines |
| Redeclaring properties in constructor | Duplication drifts out of sync | nvArgs.?ClassName |
Believing (1,:) rejects columns | It silently reshapes them | Use mustBeRow to reject |
Believing double rejects char | It silently converts to ASCII before validators run | Drop the double class spec and use {mustBeNumeric} alone, or {mustBeA(x,"double")} for strict class check |
Using [] sentinel for computed defaults | Over-engineered, needs custom validator | = expression referencing earlier args |
Replacing @ischar with mustBeTextScalar | Widens contract to accept strings | Use mustBeA(x,'char') for strict fidelity |
Using (1,1) string {mustBeTextScalar} | Class spec converts 42 → "42" before validator | Use {mustBeTextScalar} alone (no class spec) |
Replacing validatestring with mustBeMember | validatestring does case-insensitive prefix matching ('AU' → 'auto') and returns the canonical form; mustBeMember is exact-match only | Keep validatestring inside the body. Use the arguments block only for the type/size guard: mode {mustBeTextScalar} then mode = validatestring(mode, {...}) |
Omitting mustBeReal for numeric args | Complex values pass mustBeNumeric, mustBeFinite, and mustBeInteger silently — 1+2i is a finite numeric integer | Add mustBeReal whenever a complex input would be nonsensical (indices, sizes, counts, physical scalars) |
Renaming ~ to obj/this in arguments block | ~ is a valid placeholder name in arguments blocks — renaming reintroduces the lint warning the original ~ suppressed | Keep ~, no class/size spec, no %#ok pragma |
Declaring multiple names in arguments (Output, Repeating) | MATLAB errors with MultipleRepeatingOutputs — only one name is allowed | Declare a single output name; pack groups of values into that one cell array and have the caller request N * groupSize outputs |
Claiming optional positional args and (Repeating) are mutually exclusive | They aren't — required + optional + repeating + name-value all compose legally in order | See "Composition Rules". When unsure, write the function and let MATLAB's parse-time error identifier (e.g. OptionalAfterRepeating, PositionalAfterNamed) tell you what's actually wrong |
Assuming an unknown Name=Value errors loudly when the function has arguments (Repeating) | It doesn't. With a (Repeating) block present, an unrecognized Name=Value is silently absorbed as two positional repeating args (name token, then value). One bad pair also reclassifies preceding valid name-value args back to positional, so set options revert to their defaults. (Without (Repeating), the same call errors with MATLAB:TooManyInputs.) | A common way to land here: .?ClassName against a class with no public-settable properties (e.g. .?onCleanup) — the import exposes nothing, so every NV the caller writes against it is unknown. Pick a class with public-set properties. When debugging "why is my NV default showing up?", check the call for any unrecognized Name= — one bad name poisons the whole NV section |
Validators Quick Reference
| Validator | Purpose | Note |
|---|---|---|
mustBeFloat | Accept single or double only | Rejects int, char |
mustBeA(x, classes) | Strict class check, no conversion | mustBeA(x, ["single","double"]) |
mustBeBetween(x, lo, hi, type) | Range check | R2025a+. Pre-R2025a: use mustBeGreaterThan/mustBeLessThan |
mustBeNonNan | Reject NaN values | Built-in, not custom |
mustBeMatrix | Require 2D (M-by-N) | R2024b+ |
mustBeRow | Require 1-by-N | R2024b+. Rejects columns unlike (1,:) |
mustBeVector | Accept row or column | Flexible orientation |
mustBeSorted | Elements in sorted order | R2026a+ |
For the complete validator reference, see references/validators-reference.md.
Copyright 2026 The MathWorks, Inc.
Files
- ATTRIBUTION.mdAdded by AutoGineer1.1 KiB
- LICENSELicence file added by AutoGineer1.4 KiB
- SKILL.md22.0 KiB
- manifest.yaml388 B
- references/examples/dot-question-syntax.md2.7 KiB
- references/examples/repeating-args.md3.8 KiB
- references/migration-guide.md6.0 KiB
- references/validators-reference.md7.0 KiB
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- MathWorks
- Publisher
- MathWorks (Official)
- Source
- matlab/matlab-agentic-toolkit · skills-catalog/matlab-programming/matlab-validate-function-arguments · commit 2a7f215
- Licence
- BSD 2-Clause License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE.md)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by MathWorks.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download matlab-validate-function-arguments.zip