Debug
mash.debug · Platform
mash.debug shows what a script is holding. Use it when a value isn’t what you expected: what type is this, what methods does it have, what does it look like right now. It also writes to the debug output, which stands apart from printline so you can tell your real output from your notes.
How it works
Section titled “How it works”print and dnd write marked-off blocks. The text is wrapped in <~debug~> and </~debug~> lines, so debug output is easy to spot (and to filter out). print shows a value. dnd (“dump and die” elsewhere, though here it doesn’t stop the script) shows it too, but renders a record as its readable fields and any other object as its class name, and stops at six levels of nesting.
Dumps show only what a script may read. A database record appears as its readable fields. Any other object appears as <ClassName>. Secrets such as credentials and tokens never show, even if you dump the object that holds them.
getType and getClass name things. getType answers string, integer, double, boolean, array, object or NULL. For an object, getClass gives its short name, such as WrappedCarbon (a date), Collection or File. A value that isn’t an object has no class, and getClass gives null.
getMethods and getProperties list what’s there. getMethods(obj) gives each method the script can call, with its arguments. getProperties(obj) gives the public properties and their values. Neither shows anything the script isn’t allowed to use.
Common tasks
Section titled “Common tasks”Check a value’s type when a comparison surprises you:
set qty to "12"printline mash.debug.getType(qty)printline mash.debug.getType(12)printline mash.debug.getType(1.5)stringintegerdoubleAsk an object what it is, and what it can do:
set d to mash.date.parse("2026-11-03")printline mash.debug.getClass(d)printline mash.debug.getMethods(mash.string)["levenshtein"]WrappedCarbonArray [ { "name": "str1", "optional": false }, { "name": "str2", "optional": false }]Leave a marked note in the output:
mash.debug.print({step: "after filter", rows: 3})<~debug~>Dictionary { "step": "after filter", "rows": 3}</~debug~>Watch out for
Section titled “Watch out for”- Debug output is real output. Remove
mash.debug.printcalls before a script goes live, or an automation’s log fills with notes. - Don’t expect internals.
getClassgives short names on purpose, so don’t write a script that depends on one. It’s for you to read.
See also
Section titled “See also”Talking to the outside world and When things go wrong.
Methods
Section titled “Methods”debug.dnd(var: mixed)
Dump a value for debugging.
⚠ Was a bare var_dump, which reaches past every MaSH access rule: it prints an object’s private and protected state by reflection, so mash.debug.dnd(file.share) dumped the share’s service-account credentials and mash.debug.dnd(mash.user()) the password hash and decrypted tokens — none of which the script could read any other way (found 2026-10-02). Now it renders only what a script is allowed to see: a model as its MaSH-visible attributes, any other object as its class name, scalars and arrays in full (bounded).
getClass
Section titled “getClass”debug.getClass(object: mixed) → string
Get the class name of an object (its short name).
⚠ The short name only, as anything a person reads names a class (2026-09-24): the namespace advertised Foldr’s internals and the libraries it embeds, and pinned scripts to them — ut-mash-sas broke on a refactor that changed no behaviour a script could see.
getMethods
Section titled “getMethods”debug.getMethods(object: mixed) → array
The methods a script can call on an object, with their parameters.
⚠ Was every public PHP method, including the ones the access rules refuse (#[MashHidden], _-prefixed) and the whole framework surface of a model — a list of exactly what a sandboxed author should not try. Only what CompiledScope would let the script call is listed now: nothing on a model unless it is #[MashExpose]d.
getProperties
Section titled “getProperties”debug.getProperties(object: mixed) → array
The PUBLIC properties of an object, by name and value.
⚠ Was ReflectionObject::getProperties() with no filter and a stray top-level dnd($props): it read private and protected state — a model’s raw attributes, a wrapper’s injected services and their credentials — none of it reachable through the normal access rules (found 2026-10-02). Public-only now, and for an Eloquent model only its MaSH-visible attributes, so this reveals nothing the dot operator would refuse.
getType
Section titled “getType”debug.getType(var: mixed) → string
Get the type of a variable.
debug.print(value: mixed)
Print a value to the debug output