Blog

Luis Majano

September 11, 2026

Spread the word


Share your thoughts

You call writeDump() on an ORM entity or a very rich class graph . The browser locks up. Thirty seconds later you get a page with forty thousand rows on it, you scroll for a while, you give up, and you go edit your code to dump a sub-key instead. Or worse, you crash the server.

Everyone has done this. Debugging your debugging is a bad use of an afternoon.

BoxLang 1.17.0 fixes it with two independent knobs, and the important part is that they are independent.

depth: How Far Down

depth controls how many levels of nesting the dump recurses into. It is 1-based: -1 is unlimited and the default, 0 shows nothing, 1 shows the top level with no recursion, 2 recurses once.

// Just the top level, no recursion at all
writeDump( var = complexObject, depth = 1 )

// Top level plus two levels down
writeDump( var = complexObject, depth = 3 )

This is the knob for "I want to see the shape of this thing, not its contents."

maxRows: How Wide

maxRows is new in 1.17.0, and it controls the maximum number of keys, array elements, or query rows shown per level. Same 1-based semantics: -1 unlimited and default, 0 nothing, 1 a single row.

// First 10 items of a 50,000 row array
writeDump( var = bigArray, maxRows = 10 )

This is the knob for "the structure is fine, there is just too much of it."

The Point Is That They Compose

Depth and breadth used to be tangled together. Now they are not, and that means you can slice a huge object down to exactly the window you want to look at:

// Three levels deep, five entries per level.
// A readable view of an object that would otherwise
// render tens of thousands of rows.
writeDump(
	var     = orm.getEntity( "Customer", 1 ),
	depth   = 3,
	maxRows = 5,
	label   = "Customer aggregate, trimmed"
)

Three levels down tells you how the aggregate is assembled. Five entries per level tells you what the data looks like. Neither answer required loading the whole graph into the browser, and neither required you to change the code you were trying to debug.

Both arguments apply to HTML output only.

Some combinations worth keeping in your head:

// Shape only. What keys exist at the top?
writeDump( var = config, depth = 1 )

// Is this array of structs shaped the way I think?
writeDump( var = records, depth = 2, maxRows = 3 )

// Everything, but do not drown me in any single collection
writeDump( var = appState, maxRows = 20 )

top Is Deprecated

top is superseded by maxRows. It still works for backwards compatibility, and when maxRows is not also passed its value is used as maxRows, but it logs a deprecation warning when used.

// Legacy. Still functional, logs a deprecation warning.
writeDump( var = bigArray, top = 10 )

// Current
writeDump( var = bigArray, maxRows = 10 )

If you are writing new BoxLang, use depth and maxRows. Reach for top only where you are maintaining older code that already had it.

One Behavior Change to Check

Everything else about writeDump() is unchanged. label, expand, abort, output, format, and showUDFs all behave exactly as they did.

While you are in there, one small related improvement: dump() now renders a java.lang.Character using the same compact template as a String rather than a generic object dump (BL-2638).

dump( "Alice".charAt( 1 ) )
// Dumps like a one-character string, not a raw Character object

That Wraps the Series

Four posts, four features:

  1. Module Inception, modules that contain modules with real class loader isolation
  2. boxlang check, syntax validation that never executes and speaks JSON
  3. Encrypted Config Secrets, bxsecret: and the seed that decrypts it
  4. writeDump() control, depth and maxRows as orthogonal knobs

There is more in 1.17.0 than these four: include is now enforced relative, evaluate() moved out of the core into the opt-in bx-unsafe-evaluate module, xmlParse() gained XXE controls, JARs are no longer locked on Windows so hot reload finally works, and a background watchdog reclaims the parser cache that long-running servers used to accumulate and never release. The full release post covers all of it.

Resources

Add Your Comment

Recent Entries

Your ColdFusion Upgrade Passed. Did Your Business Workflows?

Your ColdFusion Upgrade Passed. Did Your Business Workflows?

The server restarted. The administrator shows the expected version. Your homepage loads, and a few familiar screens look fine.

Would you tell the business the upgrade is complete?

Consider an illustrative scenario: a customer submits an order after an upgrade. The application saves it and displays a confirmation page. But the confirmation email never arrives, and the scheduled process that sends the order to fulfillment has not completed.

From the browser, the transaction...

Maria Jose Herrera
Maria Jose Herrera
October 22, 2026
Updating Adobe ColdFusion isn't always just installing the latest patch

Updating Adobe ColdFusion isn't always just installing the latest patch

Keeping Adobe ColdFusion updated is an important part of maintaining a secure and reliable application environment.

But applying a ColdFusion update is not always as simple as installing the latest patch and restarting the server.

Updates can include security fixes, library upgrades, JVM-related changes, changes to the ColdFusion Administrator, updated packages, bug fixes, and changes in runtime behavior. Most updates will not cause problems for most applications. But when you'r...

Cristobal Escobar
Cristobal Escobar
October 21, 2026
BoxLang AI 3.6: Your Agent Now Has Eyes, Ears, and a Voice

BoxLang AI 3.6: Your Agent Now Has Eyes, Ears, and a Voice

Ortus Solutions today announces BoxLang AI 3.6, the release that connects the AI framework to the rest of the BoxLang productivity platform. Your agents can now drive a real browser via bx-playwright, speak and master audio via bx-audio, stream text-to-speech token by token, talk to any MCP server over stdio — and do all of it with the same fluent BoxLang syntax they always have.

Luis Majano
Luis Majano
October 20, 2026