fix: preserve string default values like '1.0' for form-urlencoded re…
Bug Fix Analysis: Issue #10610 - String Default "1.0" Converted to "1"
Bug Description
When using Swagger-UI with application/x-www-form-urlencoded request bodies, string properties with default values like "1.0" were being incorrectly converted to "1" (losing the decimal point) when:
- The default value is displayed in the form
- The request is executed
- The curl command is generated
This is problematic because values like version tags (e.g., "1.0") should remain as strings and not be converted to numbers.
Root Cause
The bug occurred at multiple points in the codebase:
-
getDefaultRequestBodyValuefunction: When generating default values from schema,getSampleSchemamight return numeric values for string-typed properties if the default looked like a number. -
Initial value setting in RequestBody component: When setting initial values for form fields, the code wasn't preserving string defaults verbatim.
-
Request execution in actions.js: When processing the request body before execution, values weren't being properly coerced to strings for string-typed properties.
-
Reset functionality: When resetting form values, JSON parsing might lose string precision.
Fixes Applied
1. Fix in getDefaultRequestBodyValue (request-body.jsx:31-39)
const isFormLike = mediaType === "application/x-www-form-urlencoded" || mediaType.indexOf("multipart/") === 0
if (isFormLike && schema && schema.type === "object" && schema.properties && exampleValue && typeof exampleValue === "object") {
Object.entries(schema.properties).forEach(([prop, propSchema]) => {
const propType = Array.isArray(propSchema?.type) ? propSchema.type[0] : propSchema?.type
if (propType === "string" && propSchema && Object.prototype.hasOwnProperty.call(propSchema, "default")) {
exampleValue[prop] = String(propSchema.default)
}
})
}
What it does: After getting sample schema values, it explicitly converts string-typed properties with defaults back to strings using String(propSchema.default), preserving values like "1.0".
2. Fix in RequestBody Component (request-body.jsx:192-202)
// If schema defines a default and the property is string-typed, prefer it verbatim.
// This preserves values like "1.0" exactly as specified by the spec.
if (objectType === "string") {
const schemaDefault = schema.get("default")
if (schemaDefault !== undefined) {
initialValue = String(schemaDefault)
} else if (typeof initialValue !== "string") {
// Otherwise ensure the sampled value is coerced to string.
initialValue = String(initialValue)
}
}
What it does: When setting initial values for form fields, if the schema has a default value and the property type is string, it uses String(schemaDefault) to preserve the exact string value.
3. Fix in Request Execution (actions.js:442-453)
req.requestBody = requestBody
.map(
(val, key) => {
const propSchema = properties.get(key) || ImmutableMap()
const schemaType = propSchema.get("type")
let outVal = ImmutableMap.isMap(val) ? val.get("value") : val
// If schema says string but value is not string, coerce
if (schemaType === "string" && typeof outVal !== "string" && outVal !== undefined && outVal !== null) {
outVal = String(outVal)
}
return outVal
}
)
What it does: Before executing the request, it ensures that all string-typed properties are converted to strings. This prevents numeric coercion that could turn "1.0" into 1.
4. Fix in Reset Functionality (OperationContainer.jsx:145-148)
if (schemaType === "string" && key in jsonRequestBodyValue && typeof jsonRequestBodyValue[key] !== "string") {
jsonRequestBodyValue[key] = String(jsonRequestBodyValue[key])
}
What it does: When resetting form values, it ensures string-typed properties remain as strings after JSON parsing.
How to Test the Fix
Manual Testing Steps
- Create a test OpenAPI spec with the following content:
openapi: 3.0.1
info:
title: Reproducer
version: "1.0"
paths:
/test:
post:
operationId: testOp
requestBody:
content:
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/Example'
responses:
200:
description: "Success"
components:
schemas:
Example:
type: object
properties:
versionTag:
type: string
default: "1.0"
-
Load the spec in Swagger-UI:
- Use https://editor.swagger.io/ or a local instance
- Paste the spec above
-
Test the default value display:
- Click on the
/testPOST operation - Click "Try it out"
- Verify that the
versionTaginput field shows"1.0"(with quotes if displayed as JSON, or just1.0in the input field) - The value should NOT be
1or"1"
- Click on the
-
Test the curl command:
- Click "Execute" or check the generated curl command
- The curl command should show:
-d 'versionTag=1.0' - It should NOT show:
-d 'versionTag=1'
-
Test with user input:
- Change the value to something else (e.g.,
"2.0") - Execute the request
- Verify the curl command shows:
-d 'versionTag=2.0' - Reset the form
- Verify the value returns to
"1.0"(not"1")
- Change the value to something else (e.g.,
Automated Test (Cypress)
Create a test file: test/e2e-cypress/e2e/bugs/10047.cy.js
describe("#10047: String default '1.0' preserved for form-urlencoded", () => {
it("should preserve string default value '1.0' exactly as specified", () => {
cy
.visit("?url=/documents/bugs/10047.yaml")
.get("#operations-default-testOp")
.click()
// Expand Try It Out
.get(".try-out__btn")
.click()
// Check that the default value is "1.0" (not "1")
.get(`.parameters[data-property-name="versionTag"] input`)
.should("have.value", "1.0")
// Execute the request and check the curl command
.get(".btn.execute")
.click()
// Check that the curl command contains versionTag=1.0
.get(".curl")
.should("contain", "versionTag=1.0")
.should("not.contain", "versionTag=1")
})
})
Create the test spec: test/e2e-cypress/static/documents/bugs/10047.yaml
openapi: 3.0.1
info:
title: Reproducer
version: "1.0"
paths:
/test:
post:
operationId: testOp
requestBody:
content:
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/Example'
responses:
200:
description: "Success"
components:
schemas:
Example:
type: object
properties:
versionTag:
type: string
default: "1.0"
Expected Behavior After Fix
✅ Default value "1.0" is displayed correctly in the form
✅ The value "1.0" is preserved when executing the request
✅ The curl command shows versionTag=1.0 (not versionTag=1)
✅ Resetting the form restores the value to "1.0"
✅ User can change the value and it's preserved correctly
Files Modified
-
src/core/plugins/oas3/components/request-body.jsx- Fixed default value generation and initial value setting -
src/core/plugins/spec/actions.js- Fixed request body processing before execution -
src/core/containers/OperationContainer.jsx- Fixed reset functionality
The fix(Screenshot)-