Critical Issue: Object Input Properties Work in Expression Playground but Return Null in Function Stack - Comprehensive Analysis & Solutions

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?

1 reply