6.3 KiB
DOTENV Parameter Flattening Fix
Date: 2026-02-09 Status: Complete Impact: Bug Fix - Critical
Problem
The core.http_request action was failing when executed, even though the HTTP request succeeded (returned 200 status). Investigation revealed that the action was receiving incorrect parameter values - specifically, the url parameter received "200" instead of the actual URL like "https://example.com".
Root Cause
The issue was in how nested JSON objects were being converted to DOTENV format for stdin parameter delivery:
- The action YAML specified
parameter_format: dotenvfor shell-friendly parameter passing - When execution parameters contained nested objects (like
headers: {},query_params: {}), theformat_dotenv()function was serializing them as JSON strings - The shell script expected flattened dotted notation (e.g.,
headers.Content-Type=application/json) - This mismatch caused parameter parsing to fail in the shell script
Example of the bug:
// Input parameters
{
"url": "https://example.com",
"headers": {"Content-Type": "application/json"},
"query_params": {"page": "1"}
}
Incorrect output (before fix):
url='https://example.com'
headers='{"Content-Type":"application/json"}'
query_params='{"page":"1"}'
The shell script couldn't parse headers='{...}' and expected:
headers.Content-Type='application/json'
query_params.page='1'
Solution
Modified crates/worker/src/runtime/parameter_passing.rs to flatten nested JSON objects before formatting as DOTENV:
Key Changes
- Added
flatten_parameters()function: Recursively flattens nested objects using dot notation - Modified
format_dotenv(): Now callsflatten_parameters()before formatting - Empty object handling: Empty objects (
{}) are omitted entirely from output - Array handling: Arrays are still serialized as JSON strings (expected behavior)
- Sorted output: Lines are sorted alphabetically for consistency
Implementation Details
fn flatten_parameters(
params: &HashMap<String, JsonValue>,
prefix: &str,
) -> HashMap<String, String> {
let mut flattened = HashMap::new();
for (key, value) in params {
let full_key = if prefix.is_empty() {
key.clone()
} else {
format!("{}.{}", prefix, key)
};
match value {
JsonValue::Object(map) => {
// Recursively flatten nested objects
let nested = /* ... */;
flattened.extend(nested);
}
// ... handle other types
}
}
flattened
}
Correct output (after fix):
headers.Content-Type='application/json'
query_params.page='1'
url='https://example.com'
Testing
Unit Tests Added
test_format_dotenv_nested_objects: Verifies nested object flatteningtest_format_dotenv_empty_objects: Verifies empty objects are omitted
All tests pass:
running 9 tests
test runtime::parameter_passing::tests::test_format_dotenv ... ok
test runtime::parameter_passing::tests::test_format_dotenv_empty_objects ... ok
test runtime::parameter_passing::tests::test_format_dotenv_escaping ... ok
test runtime::parameter_passing::tests::test_format_dotenv_nested_objects ... ok
test runtime::parameter_passing::tests::test_format_json ... ok
test runtime::parameter_passing::tests::test_format_yaml ... ok
test runtime::parameter_passing::tests::test_create_parameter_file ... ok
test runtime::parameter_passing::tests::test_prepare_parameters_stdin ... ok
test runtime::parameter_passing::tests::test_prepare_parameters_file ... ok
test result: ok. 9 passed; 0 failed; 0 ignored; 0 measured
Code Cleanup
- Removed unused
value_to_string()function - Removed unused
OutputFormatimport fromlocal.rs - Zero compiler warnings after fix
Files Modified
-
crates/worker/src/runtime/parameter_passing.rs- Added
flatten_parameters()function - Modified
format_dotenv()to use flattening - Removed unused
value_to_string()function - Added unit tests
- Added
-
crates/worker/src/runtime/local.rs- Removed unused
OutputFormatimport
- Removed unused
Documentation Created
docs/parameters/dotenv-parameter-format.md- Comprehensive guide covering:- DOTENV format specification
- Nested object flattening rules
- Shell script parsing examples
- Security considerations
- Troubleshooting guide
- Best practices
Deployment
- Rebuilt worker-shell Docker image with fix
- Restarted worker-shell service
- Fix is now live and ready for testing
Impact
Before Fix
core.http_requestaction: FAILED with incorrect parameters- Any action using
parameter_format: dotenvwith nested objects: BROKEN
After Fix
core.http_requestaction: Should work correctly with nested headers/query_params- All dotenv-format actions: Properly receive flattened nested parameters
- Shell scripts: Can parse parameters without external dependencies (no
jqneeded)
Verification Steps
To verify the fix works:
- Execute
core.http_requestwith nested parameters:
attune action execute core.http_request \
--param url=https://example.com \
--param method=GET \
--param 'headers={"Content-Type":"application/json"}' \
--param 'query_params={"page":"1"}'
- Check execution logs - should see flattened parameters in stdin:
headers.Content-Type='application/json'
query_params.page='1'
url='https://example.com'
- Verify execution succeeds with correct HTTP request/response
Related Issues
This fix resolves parameter passing for all shell actions using:
parameter_delivery: stdinparameter_format: dotenv- Nested object parameters
Notes
- DOTENV format is recommended for shell actions due to security (no process list exposure) and simplicity (no external dependencies)
- JSON and YAML formats still work as before (no changes needed)
- This is a backward-compatible fix - existing actions continue to work
- The
core.http_requestaction specifically benefits as it uses nestedheadersandquery_paramsobjects
Next Steps
- Test
core.http_requestaction with various parameter combinations - Update any other core pack actions to use
parameter_format: dotenvwhere appropriate - Consider adding integration tests for parameter passing formats