Problem Summary
I’ve spent considerable time debugging what appears to be a fundamental inconsistency in Xano’s object handling between the Expression Playground and actual Function Stack execution. When accessing nested object properties (e.g., $input.object.property
), the Expression Playground shows correct values while the Function Stack returns null with identical input data.
Detailed Investigation
Scenario: Building an endpoint to selectively update ICP fields using an object input icp_edits
.
Expected Behavior:
```json
Input: { "icp_edits": { "icp_name": "Test Value" } }
Expression: $input.icp_edits.icp_name
Expected Result: "Test Value"
```
Actual Results:
- Expression Playground: ✅ Returns “Test Value”
- Function Stack Execution: ❌ Returns null
What I Tested (All Failed)
1. Basic Conditionals: $input.icp_edits != null
always false
1. Different Operators: !==
, ===
, various null checks
1. Community Filter Syntax: ($input | get:"icp_edits" | count) > 0
1. Xano’s Official Filters: set_ifnotnull
with path/value configuration
1. Try/Catch Approach: No errors thrown, but still null values
1. Direct Property Access: $input.icp_edits.icp_name
(works in playground, fails in execution)
### Community Research
This isn’t an isolated issue. Found multiple posts describing identical problems:
- “Expression works in the playground but returns null in the ‘update variable’ function”
- “Critical Bug: Create Variable Step Always Returns Null for Array (concat)”
- Various null detection and object access failures
### Root Cause Analysis
Core Issue: Xano’s Expression Playground and Function Stack use different execution contexts for variable resolution. Object property access is fundamentally unreliable in production workflows.
### Proven Solutions
#### Solution 1: Flatten Input Structure (Recommended)
Replace object inputs with individual parameters:
```json
// Instead of:
{ "icp_edits": { "icp_name": "Value", "icp_description": "Value" } }
// Use:
{ "icp_name_edit": "Value", "icp_description_edit": "Value" }
```
Implementation:
```
// Edit Record fields:
icp_name: $input.icp_name_edit ? $input.icp_name_edit : $var.existing_record.icp_name
icp_description: $input.icp_description_edit ? $input.icp_description_edit : $var.existing_record.icp_description
```
#### Solution 2: JSON String Serialization
For complex objects, serialize to JSON string:
```javascript
// Frontend: JSON.stringify(objectData)
// Xano: Parse JSON step to convert string back to object
```
### AI-Assisted Problem Solving
I used advanced AI models (OpenAI O3, Claude Sonnet 4, DeepSeek R1) throughout this investigation to:
- Systematically test different approaches
- Research community solutions and best practices
- Analyze the technical root cause
- Develop comprehensive workarounds
The AI assistance was invaluable in maintaining systematic debugging and exploring solutions I might have missed.
### Recommendation for Xano Team
This appears to be a core platform issue where:
1. Expression Playground misleads developers about what works in production
1. Object property access fails silently instead of throwing errors
1. Documentation doesn’t warn about these limitations
### For Other Developers
Avoid These Patterns:
- ❌ Nested objects in API inputs
- ❌ set_ifnotnull
with nested object paths
- ❌ Complex conditionals on object existence
Use These Instead:
- ✅ Flat parameter structures
- ✅ JSON string parsing when objects are necessary
- ✅ Simple ternary logic for optional updates
- ✅ Top-level primitive inputs (strings, numbers, booleans)
### Time Investment
This debugging session took ~2 hours for what should have been a 10-minute implementation, highlighting the significant productivity impact of this limitation.
Has anyone else encountered this object handling inconsistency? Are there additional workarounds the community has discovered?